Vue.js 性能要点:事件委托

Vue、React 这些框架的出现为前端开发带来了很大的便捷,但是享受这些便捷的同时我们不应忘记之前我们掌握的优化方法。

在 Vue 中为列表中每一元素绑定事件非常方便,@eventName="handler" 即可,但是方便的同时带来了性能上的不友好。

如下我们采用两种方式监听 .list .itemclick 事件。

绑定事件到每一个 .item

<template>
  <div id="app">
  <div class="list">
    <div class="item"
      @click="onClickItem"
      v-for="(item, idx) in list"
      :key="idx">{{ idx }}</div>
    </div>
  </div>
</template>

<script>
const getInitialData = () => ({
  list: new Array(100),
});
export default {
  data: getInitialData,
  name: 'App',
  methods: {
    onClickItem() {
      alert('click');
    },
  },
};
</script>

绑定事件到 .list

<template>
  <div id="app">
  <div class="list" @click="onClickList($event)">
    <div class="item"
      v-for="(item, idx) in list"
      :key="idx">{{ idx }}</div>
    </div>
  </div>
</template>

<script>
const getInitialData = () => ({
  list: new Array(100),
});
export default {
  data: getInitialData,
  name: 'App',
  methods: {
    onClickList(event) {
      const target = event.target;
      if (target.className === 'item') {
        alert('click');
      }
    },
  },
};
</script>

以下分别是两种方式的内存快照:

EventListener On Item

EventListener On List

可以看出使用事件委托少了 $121 - 22 = 19$ 个 EventListener 对象。随着 .item 元素的增多,绑定事件到 .item 会使内存消耗呈线性增长。