[Vue] 关于v-for批量渲染绑定事件事件代理

结论:
只有在非常多的节点中(v-for渲染数量至少超过1千行),使用事件代理会提高一点性能,否则事件绑定在每个节点中几乎没有差别。

首先vue源码没有做事件代理
vue论坛开发者回复: https://forum.vuejs.org/t/is-...
实例证明:https://blog.csdn.net/supming...

那事件代理主要有什么作用?
1、动态生成和销毁子节点时,无需主动的维护子节点事件。(维护子节点事件: addEventListener, removeEventListener)
2、用一个父节点代理多个子节点的事件处理程序,减少内存开销,提升整体性能。

从vue的角度出发
1、在使用v-for时,使用v-on: 或者 @ 这种简单的语法就能给批量渲染的每个元素都绑定上事件;并且当组件销毁时,vue也会自动帮我们将所有的事件处理器都移除掉。所以事件代理的第1个作用vue已经帮我们做到了。
2、在v-for中,给元素绑定的都是相同的事件。所以除非批量渲染极多元素,普通情况下可以直接在每个子元素上绑定事件。在v-for渲染数量不多的情况下和使用事件代理的性能差别微乎其微,在这种情况下无需使用事件代理。

关于性能的区别:
生成十万个 span 节点,通过devTools中的 performance monitor 来监控内存占用率和事件监听器的数量,对比以下 3 种情况:
1、不使用事件代理,每个 span 节点绑定一个 click 事件,并指向同一个事件处理程序


      v-for="(item, index) of 100000"
    :key="index"
    @click="handleClick"
  >
    {{item}}
 

2、不使用事件代理,每个 span 节点绑定一个 click 事件,并指向不同的事件处理程序


      v-for="(item, index) of 100000"
    :key="index"
    @click="function () {}"
  >
    {{item}}
 

3、使用事件代理


      v-for="(item, index) of 100000"  
    :key="index"
  >
    {{item}}
 

[Vue] 关于v-for批量渲染绑定事件事件代理_第1张图片
[Vue] 关于v-for批量渲染绑定事件事件代理_第2张图片
[Vue] 关于v-for批量渲染绑定事件事件代理_第3张图片

可以看到第三张图内使用事件代理的情况下,监听器数量和内存占用率都比前两种方式要少。

同时对比 3 个图中监听器的数量以及我以往阅读 vue 源码的过程中,并没有发现 vue 会自动做事件代理,但是一般给 v-for 绑定事件时,都会让节点指向同一个事件处理程序(上面第二种情况可以运行,但是 eslint 会警告),一定程度上比每生成一个节点都绑定一个不同的事件处理程序性能好,但是监听器的数量仍不会变,所以使用事件代理会更好一点。(事件代理的方式只用了一个监听器,而直接绑定的方式使用了10万个监听器)

上面批量渲染的例子和图来自:
https://github.com/Advanced-F...

你可能感兴趣的