【问题标题】:Why does Event Delegation save memory?为什么事件委托可以节省内存?
【发布时间】:2021-05-01 21:25:27
【问题描述】:

我试图了解添加事件时“addEventListener”的工作原理,它保存在哪里? DOM 树?还是某个记忆的地方?但是找不到答案,我见过的所有帖子都说“你不能”,因为它没有标准,每个浏览器都有不同的实现。

所以我试图跳过它,但有一个关于事件委托的问题。在许多帖子中,人们说事件委托可以节省内存,因为我们不必将事件侦听器附加到每个组件。但我想,我必须了解 addEventListener 是如何工作的,才能理解为什么事件委托可以节省内存。

那么,事件委托对内存有效的原因是什么?

【问题讨论】:

  • 但真的吗?我见过很多 JS 问题,但是太多 addEventListeners 消耗太多内存从来都不是其中之一。我总是找到使用事件委托来简化代码逻辑的原因,而不是出于性能原因。
  • 也不会影响速度超过内存使用?
  • @CertainPerformance 我也没有听说过,但人们在很多帖子中都说它可以节省内存,所以我只想知道它是如何工作的:/ 我无法区分它是如何节省内存和addEventListener 是如何工作的。
  • @OtherMe 不管怎样,事件发生了,必须进入目标阶段和气泡。速度有提升吗?我还没想好。

标签: javascript browser cross-browser addeventlistener event-delegation


【解决方案1】:

在浏览器内存的某个地方,有一个数据结构,其中包含每个元素的事件侦听器列表。如果您为 100 个不同的元素分别调用 addEventListener(),它将在此表中创建 100 个条目。

但是如果你使用事件委托,你只需要调用一次addEventListener(),所以表中只有1个条目。

您实际上可以通过打开开发者工具的元素面板中的事件监听器标签来查看这些数据的表示。

但是,您节省的内存量可能不是很大。每个侦听器可能只是几个指针,一个指向表示事件类型(单击、更改等)的对象,另一个指向回调函数。如果所有 100 个事件侦听器都调用同一个函数,那么只有一个函数对象和 100 个指向它的指针。如果函数是一个闭包,也会有一个环境对象包含它关闭的变量,这会增加一点内存使用,但不会太多。

另一方面,当您使用委托时,回调函数需要做额外的工作来确定事件目标是否是适当的嵌套元素。这使它变慢了一点。如果事件在容器元素中的一个元素上触发,但不是您被委派给的元素之一(并且将随着事件冒泡而重复运行),它也会被调用,因此该函数运行得更频繁。如果内存真的很宝贵,这将是一个经典的时间/空间权衡。

在实践中,委托不是用来节省内存的,它是用来简化设计的。当您向 DOM 动态添加元素或更改事件绑定所依赖的属性(例如类名)时,最常使用它。委托允许您定义一次事件侦听器,而不必在添加或修改元素时添加或删除它。

【讨论】:

    猜你喜欢
    • 2012-03-08
    • 2011-01-10
    • 2016-08-29
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多