从双端到快速:Vue 3 Diff 的进化之路

当组件状态变化,Vue 会生成一棵全新的虚拟 DOM 树。如果每次都推倒重建,页面必然卡顿。Diff 算法就是「找出最小差异」的那把手术刀。Vue 2 的双端 Diff 已经很快,Vue 3 却用「快速 Diff」让它更快。

一、为什么需要 Diff?

响应式系统只能告诉你「某个组件脏了」,却不知道「脏在哪一行节点」。Diff 负责在同层级内精确定位「新增、删除、移动、更新」,避免整棵树的重绘。

二、Vue 2 的双端 Diff

想象新旧两条虚拟节点队列,各有一头一尾两个指针:

  1. 头头比对

    新旧头节点相同 → 复用节点,两指针右移。

  2. 尾尾比对

    新旧尾节点相同 → 复用节点,两指针左移。

  3. 旧头新尾比对

    相同 → 把旧头节点移动到尾部,旧头右移、新尾左移。

  4. 新头旧尾比对

    相同 → 把旧尾节点移动到头部,新头右移、旧尾左移。

如果四步都失败,就进入「暴力查找」:在旧队列里线性搜索与新头相同的节点。找到则移动,未找到则新增。

指针相遇即结束,剩余旧节点批量删除,剩余新节点批量新增。

双端 Diff 用 O(n) 时间完成「头尾夹击」,极大减少移动次数。

三、Vue 3 快速 Diff

双端 Diff 在「乱序列表」场景仍需多次线性搜索。Vue 3 把思路翻转:

  • 先建立 key → index 的 Map,一次遍历即可知道是否存在可复用节点;
  • 再求「最长递增子序列」(LIS),把「需要移动的节点」降到最少;
  • 最后只做必要的 DOM 移动,其余节点原地复用。

结果:

  • 纯新增或纯删除场景 → O(1) 完赛;
  • 乱序场景 → O(n log n) 优于双端 Diff 的 O(n²)。

快速 Diff 把「比较」提前到内存,把「移动」推迟到最小集合,浏览器只需执行真正的 DOM 操作。

总结

Vue 2 用双端指针夹击「头尾」,Vue 3 用预序列化 + LIS 直击「最小移动」。理解指针走向,你就握住了性能优化的方向盘。

相关推荐
king王一帅4 小时前
Incremark Solid 版本上线:Vue/React/Svelte/Solid 四大框架,统一体验
前端·javascript·人工智能
C雨后彩虹6 小时前
任务最优调度
java·数据结构·算法·华为·面试
智航GIS8 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
前端工作日常9 小时前
我学习到的A2UI概念
前端
徐同保9 小时前
为什么修改 .gitignore 后还能提交
前端
一只小bit9 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui
Mr -老鬼10 小时前
前端静态路由与动态路由:全维度总结与实践指南
前端
颜酱10 小时前
前端必备动态规划的10道经典题目
前端·后端·算法
Chan1610 小时前
【 Java八股文面试 | JavaSE篇 】
java·jvm·spring boot·面试·java-ee·八股
wen__xvn10 小时前
代码随想录算法训练营DAY10第五章 栈与队列part01
java·前端·算法