作者:Breerus | 来源:互联网 | 2023-10-10 14:48
Vue3diff算法优化静态提升hoistStatic事件侦听器缓存cacheHandlers写下博客主要用来分享知识内容,并便于自我复习和总结。如有错误之处
Vue3
diff算法优化
静态提升 hoistStatic
事件侦听器缓存 cacheHandlers
写下博客主要用来分享知识内容,并便于自我复习和总结。
如有错误之处,请各位大佬指出。
diff算法优化
首先,diff算法是虚拟DOM技术的必然产物,它会对新旧虚拟DOM作对比(即diff),然后将变化的地方更新在真实DOM上。而这其中,如何快速的判别需要变化的内容,就是Vue3.0的提升。具体来看:
在Vue2.0当中,当数据发生变化,它就会新生成一个DOM树,并和之前的DOM树进行比较,找到不同的节点然后更新。但这比较的过程是全量的比较,也就是每个节点都会彼此比较。但其中很显然的是,有些节点中的内容是不会发生改变的,那我们对其进行比较就肯定消耗了时间。所以在Vue3.0当中,就对这部分内容进行了优化:在创建虚拟DOM树的时候,会根据DOM中的内容会不会发生变化,添加一个静态标记。那么之后在与上次虚拟节点进行对比的时候,就只会对比这些带有静态标记的节点。
为了方便看到结果,我们将代码转成Vue3源码就可看到效果:
对于这个静态标记为什么是数字1,PatchFlags目录中有详细叙述:
export const enum PatchFlags {// 动态文本节点TEXT = 1,// 动态 classCLASS = 1 <<1, // 2// 动态 styleSTYLE = 1 <<2, // 4// 动态属性,但不包含类名和样式// 如果是组件,则可以包含类名和样式PROPS = 1 <<3, // 8// 具有动态 key 属性,当 key 改变时,需要进行完整的 diff 比较。FULL_PROPS = 1 <<4, // 16// 带有监听事件的节点HYDRATE_EVENTS = 1 <<5, // 32// 一个不会改变子节点顺序的 fragmentSTABLE_FRAGMENT = 1 <<6, // 64// 带有 key 属性的 fragment 或部分子字节有 keyKEYED_FRAGMENT = 1 <<7, // 128// 子节点没有 key 的 fragmentUNKEYED_FRAGMENT = 1 <<8, // 256// 一个节点只会进行非 props 比较NEED_PATCH = 1 <<9, // 512// 动态 slotDYNAMIC_SLOTS = 1 <<10, // 1024// 静态节点HOISTED = -1,// 指示在 diff 过程应该要退出优化模式BAIL = -2
}
静态提升 hoistStatic
在Vue中无论元素是否参与更新,每次都会重新创建,然后再渲染。如下图所示,每次都会createVNode。
但是在Vue3中使用了静态提升后,对于不参与更新的元素,只会被创建一次,在渲染时直接复用即可:
事件侦听器缓存 cacheHandlers
默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没必要去追踪它的变化,想办法将它直接缓存起来复用就会提升性能。
从上图就可以看到,onClick果然会被视为动态绑定,它有静态标记,查看刚才提到的目录中发现,8是动态属性。开启cacheHandlers后,静态标记就不存在了,那么这部分内容也就不会进行比较了。
————————————————
版权声明:本文为CSDN博主「只爭朝夕不負韶華」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45613931/article/details/109470718