为什么JavaScript中事件委托比普通子元素事件监听性能更高?
导航点击平滑滚动两种实现的性能差异原因
以下是两种实现的代码示例:
// 实现方案1:普通子元素逐个绑定事件实现 navLink.forEach(function (item) { item.addEventListener('click', function (e) { e.preventDefault(); const navId = item.getAttribute('href'); const navEl = document.querySelector(navId); navEl.scrollIntoView({ behavior: 'smooth' }); }); });
// 实现方案2:事件委托实现 navLinks.addEventListener('click', function (e) { e.preventDefault(); // 匹配点击目标是否为导航链接 if (e.target.classList.contains('nav__link')) { const navId = e.target.getAttribute('href'); const navEl = document.querySelector(navId); navEl.scrollIntoView({ behavior: 'smooth' }); } });
两种方案的性能差异本质是逐个绑定事件和事件委托两种实现模式的差异,事件委托依托浏览器的事件冒泡机制实现,性能优势主要体现在以下几点:
- 内存占用差距大:方案1会为每一个导航链接创建独立的事件监听函数,导航项数量越多,生成的函数对象越多,占用的内存就越高。方案2全程仅在父容器上绑定1个监听函数,无论子导航项有多少,内存开销都维持在极低水平。
- 初始化执行效率更高:方案1需要遍历所有导航子元素,逐个执行事件绑定操作,导航项越多遍历和绑定的耗时越长。方案2仅需要执行1次父元素的事件绑定操作,初始化耗时几乎不受子元素数量影响。
- 无额外的动态元素维护开销:如果后续导航项是动态生成、动态增删的,方案1需要为新增的导航项重新绑定事件,删除元素前还要手动解绑事件避免内存泄漏,会产生大量额外的操作开销。方案2完全不需要处理这些逻辑,只要父容器不被销毁,新增的符合匹配规则的子元素会自动触发对应逻辑,没有额外的绑定/解绑开销。
内容的提问来源于stack exchange,提问作者alireza fazeli
相关产品推荐
相关产品推荐

