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

相关推荐
计算机魔术师2 分钟前
管谷歌的不是Pichai一个人,是一整层AI智能体
前端
米米商聊6 分钟前
图标能点,按钮就可用了吗?键盘、名称与收藏状态
前端·javascript
Younglina44 分钟前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
xy34531 小时前
Axure 9.0 内联框架加载方式
前端·ui·html·axure·原型·产品设计
xiangyun611 小时前
C++ priority_queue 底层:手撕二叉堆与 Top K 问题
c++·算法·面试·stl·1024程序员节
漫天转悠1 小时前
Vue3白屏排查实录-Transition与多根模板
vue.js·1024程序员节
陈随易2 小时前
副业搞钱点子之收入查看器
前端·后端
Profile排查笔记2 小时前
浏览器指纹逆向怎么分析:从网络请求追踪到 JavaScript 采集链
前端·人工智能·后端·自动化
hudie7652 小时前
LikeShop 二开最常改的 5 个文件(附改前改后对比)
前端·uni-app·php·个人开发
莫叫石榴姐3 小时前
半导体业务数仓建模: Lot、Wafer、Die、Recipe、OEE、YMS 建模要点
数据仓库·sql·面试·职场和发展·矩阵·1024程序员节