17.5 缓存内联事件处理函数
内联事件处理函数每次渲染都会是全新的函数,导致子组件 props 变化并触发无意义更新;用
cache数组缓存它即可避免。
一、问题:每次渲染都新建函数
<Comp @change="a + b" />
编译器会为内联表达式创建一个内联事件处理函数:
function render(ctx) {
return h(Comp, {
// 内联事件处理函数
onChange: () => (ctx.a + ctx.b),
})
}
- 每次重新渲染(
render函数重新执行)都会为Comp创建一个全新的 props 对象; props.onChange的值也是全新的函数;- 渲染器比较 props 时发现
onChange变了,于是对Comp组件执行更新 → 额外的性能开销。
二、解法:缓存到 cache 数组
把内联事件处理函数加入 cache 数组,渲染函数重新执行时优先读取缓存:
function render(ctx, cache) {
return h(Comp, {
// 将内联事件处理函数缓存到 cache 数组中
onChange: cache[0] || (cache[0] = ($event) => (ctx.a + ctx.b)),
})
}
cache由渲染器在调用渲染函数时传入,跨多次渲染持续存在;- 无论执行多少次渲染函数,
props.onChange的值始终不变,于是不会触发Comp组件更新; - 对应编译开关为
cacheHandlers。
缓存后的处理函数依然能拿到最新数据:函数体执行时才读取
ctx.a/ctx.b,缓存的只是函数本身,不是计算结果。
相关
- 17.4 预字符串化:同为减少更新开销的编译优化
- 17.6 v-once:同一个
cache数组还可以用来缓存虚拟 DOM