从双端到快速: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 直击「最小移动」。理解指针走向,你就握住了性能优化的方向盘。

相关推荐
程序员黑豆5 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC6 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea6 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
码匠许师傅6 小时前
【C++ 面试真题】聊聊 C++ 的移动语义与右值引用
java·c++·面试
浮生望6 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少7 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0077 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis8 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝9 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
Thecozzy9 小时前
大厂 AI Coding 面试大招
人工智能·面试·职场和发展