Vue3 中编译优化方面的静态提升是什么以及为何可以优化? #3
Labels
compiler-core
Problems related to compiler-core
performance
Problems related to performance
runtime-core
Problems related to runtime-core
问题
说一说 Vue3 中编译优化方面的 静态提升 是什么?以及为什么使用 静态提升 可以编译优化?
该问题可能引申自:
分析
案例来自于《Vuejs 设计与实现》
假如有如下 template 1:
以及如下的 template 2:
对于 template 1,如果没有使用静态提升,渲染函数最后会变成:
如果响应式数据
message
发生了变化,render
函数会重新执行。但对于'static text'
的p
标签而言,额外的创建行为会带来性能消耗。同理对于 template 2,如果没有使用静态提升,渲染函数最后会变成:
这里给出
renderer
的部分相关代码可以看到
patchElement
会执行patchProps
,而{ foo: "foo" } !== { foo: "foo" }
会返回true
,因此newProps
和oldProps
的处理代码都会执行,额外的处理行为无疑会带来性能消耗。解决方案
template 1
对于 template 1 的场景而言,响应式数据的更新影响到了 静态节点,导致其重复创建。因此将其提升至
render
函数外,做一个引用即可:template 2
同理 template 1 的场景中,只需要将
props
提升到render
函数外在
patchProps
时候,_hoisted_1 !== _hoisted_1
返回false
,就不会进行多余的props
对比和更新了。回答
静态提升指的是:
对于静态的树(节点),使用类似如下的代码,将其提升到
render
函数外,即是 静态树(节点)的提升可以避免其他不相干响应式数据更新触发
render
,导致静态树(节点)重复创建的问题对于动态的树(节点),如果其
props
是静态的,使用如下的代码,将其提升到render
函数外,即是 静态props
的提升可以避免在
patchProps
阶段,多余的newProps
和oldProps
的处理逻辑不足
hoistStatic
的代码还没有看,实现部分要以后补上后记
为什么要写这一篇呢?因为在
runtime-core
部分看到patchProps
的代码时候,崔大说了句:为了性能加个if (oldProps !== newProps)
语句,当时我就很不解,看了 HCY 的书,甚至还在 vue 3 里提了个 issue #5773,认为判断应该改为hasPropsChanged
。因为形如下述的这个 case:oldProps !== newProps
无论如何都会都会返回true
的。而群里的小伙伴 Salt 则直接提了个 PR #5857,认为这个判断是一个无效语句,应当删除。
后来 Evan You 回复了PR #5857,指出了 静态提升 的问题,这个判断是 有意为之。
所以我写了这篇文章,以便解答后续的小伙伴在看到
patchProps
的时候产生的困惑。产生困惑是正常的!因为此时眼光只局限在了runtime-core
中,而没有compiler-core
的大局观。仅以本篇鼓励所有学习的小伙伴,带着问题看源码,你会收获更多。The text was updated successfully, but these errors were encountered: