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

相关推荐
IT龟苓膏7 分钟前
并发深度解析】硬核手撕 ForkJoinPool + WorkStealing + CompletableFuture 底层源码与大厂面试演练
面试·职场和发展
tedcloud12318 分钟前
taste-skill部署教程:打造个性化AI推荐工作流
服务器·前端·人工智能·系统架构·edge
xinhuanjieyi31 分钟前
html修复游戏种太阳错误
前端·游戏·html
林希_Rachel_傻希希1 小时前
学React治好了我的焦虑症,1小时速通React 前20分钟。
前端·javascript·面试
Cache技术分享1 小时前
435. Java 日期时间 API - Clock 灵活获取当前时间
前端·后端
独泪了无痕2 小时前
Vue3中防御XSS攻击的“特效药”-DOMPurify
前端·vue.js·安全
小小19923 小时前
idea 配置less转化为css
前端·css·less
hhb_6183 小时前
Less嵌套避坑:优先级冲突实战解析
前端·css·less
云水一下3 小时前
Vue.js从零到精通系列(五):全局状态管理——Pinia 核心与实践
前端·javascript·vue.js
我不是外星人3 小时前
浅谈我对 AI 发展的看法
前端·ai编程·claude