惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
罗磊的独立博客
雷峰网
雷峰网
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
B
Blog RSS Feed
腾讯CDC
Apple Machine Learning Research
Apple Machine Learning Research
D
Docker
Recent Announcements
Recent Announcements
T
Tailwind CSS Blog
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
小众软件
小众软件
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
I
InfoQ
S
SegmentFault 最新的问题

博客园 - 前端路引

高精度计算插件 decimal.js 处理 JS 浮点数精度问题(0.1 + 0.2 !== 0.3) 还在痛苦前端的拖拽排序吗?SortableJS 轻松搞定 浏览器 15 个常见指纹特征,使用插件 FingerprintJS 生成浏览器指纹 Web前端入门第 90 问:JavaScript 也能无中生有的创建音频 Web前端入门第 89 问:总结 8 种跨域通信处理方案 Web前端入门第 88 问:引入 JavaScript 的 script 标签究竟有多少用法? Web前端入门第 87 问:JavaScript 中 setInterval 和 setTimeout 细节 Web前端入门第 86 问:JavaScript 中的 Web Worker 为什么能提升代码性能? Web前端入门第 85 问:JavaScript 一个简单的 IndexedDB 数据库入门示例 Web前端入门第 84 问:JavaScript sessionStorage 那些容易踩坑的地方 Web前端入门第 83 问:JavaScript localStorage 有大小限制吗?溢出会怎样? Web前端入门第 82 问:JavaScript cookie 有大小限制吗?溢出会怎样? Web前端入门第 81 问:JavaScript cookie 的读写操作 Web前端入门第 80 问:JavaScript 哪些地方需要 try...catch 异常捕获 Web前端入门第 79 问:JavaScript async & await 的异步任务进化之路 Web前端入门第 78 问:JavaScript 比较少见的模版字符串用法 Web前端入门第 77 问:JavaScript 由程序触发绑定事件的几种方式 Web前端入门第 76 问:JavaScript 鼠标事件(mouse) enter/leave 和 over/out 区别 Web前端入门第 74 问:JavaScript 事件冒泡与事件捕获
Web前端入门第 75 问:JavaScript 性能优化之事件委托(事件...
前端路引 · 2025-07-03 · via 博客园 - 前端路引

如今 Vue 大行其道,大部分开发场景直接使用 @click 就实现了事件绑定,可能都没思索过 JS 中的事件性能优化。

事件委托原理

事件委托 其主要是利用了事件冒泡这个特性。

以点击事件 click 为例:将事件绑定在父元素上,点击子元素会通过冒泡的方式触发父元素的点击事件。这种绑定事件的方式,就称之为 事件委托,也称为 事件代理

示例

利用事件委托实现点击 span 元素输出 span 元素内容:

<ul class="parent">
  <div>div 内容</div>
  <li>第 1 个 li <span>第 1 个 span 内容</span></li>
  <li>第 2 个 li <span>第 2 个 span 内容</span></li>
  <li>第 3 个 li <span>第 3 个 span 内容</span></li>
  <li>第 4 个 li <span>第 4 个 span 内容</span></li>
  <li>第 5 个 li <span>第 5 个 span 内容</span></li>
  <li>第 6 个 li <span>第 6 个 span 内容</span></li>
  <li>第 7 个 li <span>第 7 个 span 内容</span></li>
  <li>第 8 个 li <span>第 8 个 span 内容</span></li>
</ul>

<script>
  (() => {
    const parent = document.querySelector('.parent')
    parent.addEventListener('click', (event) => {
      const target = event.target
      // 判断事件响应元素是否是 span
      if (target.tagName.toLocaleLowerCase() === 'span') {
        console.log(target.innerText)
      }
    })
  })()
</script>

效果:

点击 div 和 li 元素都不会触发事件,点击 span 元素会在控制台输出元素内容。

75-1

优点

1、由于 JS 绑定的事件只有一个父元素,所以节省了内存。
2、无需针对每一个子元素绑定事件,所以减少了子元素的事件注册。
3、对于子元素的增删改不用再新注册事件,所以对子元素的操作要简单很多。
4、对于存在大量子元素的页面,由于减少了事件注册次数,所以可以提高页面性能。

缺点

既然事件委托那么有用,那么能不能直接将页面上所有的事件都委托到 body 元素上?

这想法很丰满,但显示很骨感啊,这种情况如果都绑定到最顶层的元素上,那么会导致所有的子元素都会事件冒泡,然后触发顶层元素的事件,这样反而无法做到性能优化,还造成了一些不必要的浪费,毕竟不是所有的子元素都需要响应事件!!

写在最后

性能优化这条路上,一直都存在各种话题,很多性能优化都是过犹不及,适当的场景用适当的方式才是最合理的。

代码编写并不是一蹴而就,很多时候,能实现功能就是好代码,至于性能,在一些小的需求场景,您写的代码可能都无法触发性能问题~~

坚持一个原则:不要过早优化。当我们的代码确实触发了性能问题,再考虑如何优化吧~~