已合作成功的客户

遍及全国及海外

中国

杭州,绍兴,宁波,湖州,嘉兴,温州,台州,上海,北京,南京,苏州,常州,无锡,长沙,青岛,江西,台湾,南宁,海南,成都,哈尔滨,深圳,香港,沈阳 ...

海外

美国,加拿大,丹麦,澳大利亚,新加坡,法国,智利,日本,英国 ...

合作咨询

4001-355-360

洞见

news

洞察行业新闻,实时了解最新动态

Vue3的diff算法原理

作者:admin

来源:lanyunwork

时间:2025-11-14

分享到:

核心前提:虚拟 DOM 与 Patch 过程

Vue 中,组件的渲染会生成虚拟 DOM(VNode,一个描述真实 DOM 的 JavaScript 对象)。当数据变化时,会生成新的 VNode 树,diff 算法的作用就是对比新旧 VNode 树,找到差异(“补丁”),并通过 patch 方法将差异更新到真实 DOM。

Vue3 diff 算法的核心优化与流程

Vue3 的 diff 算法主要针对 子节点列表(children) 的对比(因为大多数 DOM 变化发生在列表中),核心思路是 “精准定位差异,减少不必要的对比和 DOM 操作”。

1. 静态标记(PatchFlag):跳过静态内容

Vue3 在 编译阶段 会对模板进行分析,给 VNode 打上 静态标记(PatchFlag),标识节点是否为静态(内容不会变化),或动态部分的类型(如文本、属性、样式等)。
示例:模板 <div :id="id">Hello {{ name }}</div> 编译后,VNode 的 patchFlag 会标记为 “需要更新文本和 id 属性”,diff 时只检查这两处,无需全量对比节点的所有属性。

2. 子节点对比的核心流程(当新旧节点都有 children 时)

当新旧 VNode 都包含子节点(children 为数组)时,Vue3 会分步骤对比,核心逻辑在 patchChildren 方法中。
步骤 1:处理 “首尾快速对比”,复用可直接匹配的节点
通过 4 个指针 分别指向新旧子节点列表的首尾,快速对比首尾节点是否可复用(即 key 和 type 相同),减少中间节点的对比次数:
对比规则:
通过首尾对比,可快速复用大量连续的、未移动的节点,减少后续复杂对比的范围。
步骤 2:处理 “剩余节点”,利用 key 建立映射
当首尾对比无法匹配时,剩余节点需要通过 key 查找可复用的节点(Vue 要求列表渲染时加 key,就是为了这里的快速匹配):
步骤 3:处理 “移动与删除”,基于最长递增子序列(LIS)减少移动
经过步骤 1 和 2 后,需要处理剩余的未匹配旧节点(需删除)和已匹配节点的位置调整(需移动)。为了减少 DOM 移动操作(DOM 移动性能成本高),Vue3 引入 最长递增子序列(LIS) 算法:
举例:旧节点索引序列 [2, 1, 3, 0],其 LIS 为 [1, 3](或 [2, 3]),这两个节点无需移动,其他节点围绕它们插入,减少移动次数。
步骤 4:清理残留节点
最后,删除旧列表中未被匹配的节点(已无用),完成 diff 过程。

Vue3 vs Vue2 diff 算法的核心差异

总结

Vue3 的 diff 算法通过 编译时静态标记 减少不必要的对比,通过 首尾快速匹配 和 key 映射表 提升查找效率,最终通过 最长递增子序列 减少 DOM 移动操作,实现了比 Vue2 更高效的虚拟 DOM 更新。这些优化使得 Vue3 在大型列表和复杂组件的渲染性能上有显著提升。

 

业务咨询

微信咨询

请扫二维码
咨询项目经理

400电话

4001-355-360

获取方案

与蓝韵项目经理通话

请输入正确的手机号码格式

信息保护中请放心填写

在线咨询
 
提交成功
关闭浮窗