1.diff算法优化
首先,diff算法是虚拟DOM技术的必然产物,它会对新旧虚拟DOM作对比(即diff),然后将变化的地方更新在真实DOM上。而这其中,如何快速的判别需要变化的内容,就是Vue3.0的提升。具体来看:
在Vue2.0当中,当数据发生变化,它就会新生成一个DOM树,并和之前的DOM树进行比较,找到不同的节点然后更新。但这比较的过程是全量的比较,也就是每个节点都会彼此比较。但其中很显然的是,有些节点中的内容是不会发生改变的,那我们对其进行比较就肯定消耗了时间。所以在Vue3.0当中,就对这部分内容进行了优化:在创建虚拟DOM树的时候,会根据DOM中的内容会不会发生变化,添加一个静态标记。那么之后在与上次虚拟节点进行对比的时候,就只会对比这些带有静态标记的节点。
为了方便看到结果,我们将代码转成Vue3源码就可看到效果:
对于这个静态标记为什么是数字1,PatchFlags目录中有详细叙述:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | export const enum PatchFlags { // 动态文本节点 TEXT = 1, // 动态 class CLASS = 1 << 1, // 2 // 动态 style STYLE = 1 << 2, // 4 // 动态属性,但不包含类名和样式 // 如果是组件,则可以包含类名和样式 PROPS = 1 << 3, // 8 // 具有动态 key 属性,当 key 改变时,需要进行完整的 diff 比较。 FULL_PROPS = 1 << 4, // 16 // 带有监听事件的节点 HYDRATE_EVENTS = 1 << 5, // 32 // 一个不会改变子节点顺序的 fragment STABLE_FRAGMENT = 1 << 6, // 64 // 带有 key 属性的 fragment 或部分子字节有 key KEYED_FRAGMENT = 1 << 7, // 128 // 子节点没有 key 的 fragment UNKEYED_FRAGMENT = 1 << 8, // 256 // 一个节点只会进行非 props 比较 NEED_PATCH = 1 << 9, // 512 // 动态 slot DYNAMIC_SLOTS = 1 << 10, // 1024 // 静态节点 HOISTED = -1, // 指示在 diff 过程应该要退出优化模式 BAIL = -2 } |
2.静态提升 hoistStatic
在Vue中无论元素是否参与更新,每次都会重新创建,然后再渲染。如下图所示,每次都会createVNode。
但是在Vue3中使用了静态提升后,对于不参与更新的元素,只会被创建一次,在渲染时直接复用即可:
3.事件侦听器缓存 cacheHandlers
默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没必要去追踪它的变化,想办法将它直接缓存起来复用就会提升性能。
从上图就可以看到,onClick果然会被视为动态绑定,它有静态标记,查看刚才提到的目录中发现,8是动态属性。开启cacheHandlers后,静态标记就不存在了,那么这部分内容也就不会进行比较了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗