一句话概括Vue2 和 Vue3 的 diff 算法区别
Vue2 和 Vue3 的 diff 算法核心区别在于 优化策略和数据粒度,Vue3 通过编译时优化实现了更精确的靶向更新。
Vue2 的 diff 算法(双端比较)
- 递归同层比较:深度优先,逐层比较
- 双端指针:新旧子序列使用4个指针(旧头、旧尾、新头、新尾)进行4种比较
- 无 key 时全量比对:通过遍历查找可复用节点,性能较差
- 全量差异比对:即使静态节点也会在每次更新时比较
Vue3 的 diff 算法(快速路径 + 最长递增子序列)
- patchFlag 标记 :编译时标记动态节点类型,更新时跳过静态节点
- block 树 :收集动态子节点,形成更新区块,减少遍历范围
- 最长递增子序列优化 :对有 key 的子序列,使用贪心+二分查找 LIS,最小化移动操作
- 缓存事件处理函数:避免不必要的重新渲染
核心区别对比
| 维度 | Vue2 | Vue3 |
|---|---|---|
| 优化策略 | 运行时优化为主 | 编译时 + 运行时协同优化 |
| 静态处理 | 每次参与比较 | 编译时标记,直接跳过 |
| 更新粒度 | 组件级为主 | 元素级靶向更新(通过 patchFlag) |
| 列表更新 | 双端比较 O(n) | LIS 算法优化移动 O(nlogn) |
| 事件处理 | 每次更新可能重建 | 缓存处理函数 |
关键改进点
- 编译信息利用:Vue3 通过编译时分析,为运行时提供优化线索
- 静态提升:将静态节点提升到渲染函数外,避免重复创建
- 靶向更新:根据 patchFlag 只更新变化的属性,而非整个 VNode
- 缓存优化:对事件处理器、插槽内容等进行缓存
一句话概括 :Vue3 通过编译时标记 + 靶向更新,实现了从"全量递归比对"到"精准按需更新"的进化,显著减少了不必要的比较操作。