Vue 2 和 Vue 3 都采用了双端比较这种方法。它通过同时从新旧节点数组的头部和尾部向中间推进,使用两个指针逐步比对,能在常见场景下快速定位变化节点,减少遍历次数和 DOM 操作,提升性能
什么是“双端比较”?
**双端比较(double-ended comparison)**是一种优化 Diff 算法的策略:通过同时从头部和尾部推进对比,利用两个指针在数组两端进行同步比对,从而减少不必要的遍历和 DOM 操作,加快节点对比过程。
Vue 2 与 Vue 3 的 Diff 执行流程对比
Vue 2 的整体流程:
- 采用传统递归方式遍历新旧 vnode 树。
- 子节点对比中使用双端比较+手写条件匹配进行优化,匹配 4 种固定组合(旧头对新头、旧尾对新尾、旧头对新尾、旧尾对新头)。
- 对乱序节点通过简单的
key -> index映射处理,缺乏整体视角,移动次数较多。 - 所有逻辑集中在一个函数中,流程复杂,难以维护和扩展。
Vue 3 的整体流程:
- 整体分为头尾同步阶段 + 中间乱序节点处理阶段。
- 利用两个
while循环分别同步头部和尾部,清晰分离逻辑。 - 中间乱序节点使用
Map快速定位 + 最长递增子序列(LIS) 算法来最小化移动次数。 - 静态节点在编译阶段提前标记,运行时可直接跳过,无需对比。
- 代码模块化、职责清晰,便于维护和后续优化。
Vue 3 相比 Vue 2 的优势
| 优势点 | Vue 3 的改进说明 |
|---|---|
| 结构清晰 | 头尾同步、中间乱序、静态跳过分阶段处理,逻辑明确,比 Vue 2 的大函数更易读。 |
| 性能更优 | 通过 LIS 算法精准移动节点,最大限度减少 DOM 操作;双端同步更高效,适配大规模数据。 |
| 静态跳过 | 编译期标记静态内容,运行时跳过 Patch,避免无意义的更新,Vue 2 无此优化。 |
| 最小移动成本 | Vue 3 在乱序情况下可避免不必要的节点插入和删除,保留最多稳定节点,Vue 2 移动次数多。 |
| 更易扩展维护 | 模块化实现,逻辑拆分清晰,比 Vue 2 更便于调试、优化和添加新特性。 |
总结
Vue 3 在虚拟 DOM Diff 算法上的改进,解决了 Vue 2 在节点乱序、性能瓶颈、维护复杂度等方面的痛点。通过更系统的双端对比流程、更强的静态优化策略和精准的最小化移动逻辑,Vue 3 能够在复杂场景下实现更高性能和更强可维护性的渲染机制。