Vue 2 / Vue 3 diff算法

一句话核心结论

Vue 2 是运行时驱动的双端 diff
Vue 3 是编译期标记 + 运行时最小化更新(LIS)


Vue 2 Diff(双端比较)

核心算法

  • 双端指针 diff

  • 运行时递归对比整棵 VNode 树

    oldStart → ← oldEnd
    newStart → ← newEnd

4 种命中策略

  1. oldStart vs newStart

  2. oldEnd vs newEnd

  3. oldStart vs newEnd

  4. oldEnd vs newStart

  • key → 建立 map 查找

特点

  • 所有节点都会参与 diff

  • 静态节点也要比较

  • 列表乱序时 DOM 移动次数不稳定

优缺点

✅ 实现简单、直观

❌ 大模板 / 大列表性能不稳定


Vue 3 Diff(Block + LIS)

编译期优化(关键差异)

  • PatchFlags:标记哪些会变

  • Block Tree:只收集动态节点

    PatchFlags.TEXT
    PatchFlags.CLASS
    PatchFlags.PROPS

运行时 diff

  • 只 diff 动态节点

  • 列表更新使用 最长递增子序列(LIS)

  • 保证 最少 DOM 移动

特点

  • 静态节点完全跳过

  • diff 更"确定性"

  • 性能更稳定


Vue 2 vs Vue 3 对比表(速记)

维度 Vue 2 Vue 3
diff 时机 运行时 编译期 + 运行时
核心算法 双端指针 LIS
静态节点 参与 diff 直接跳过
列表性能 不稳定 最优
key 作用 重要 非常重要

面试标准回答模板(直接背)

Vue 2 的 diff 主要是运行时的双端比较算法,通过 key 减少 DOM 操作,但所有节点都需要参与比较。

Vue 3 在编译期引入 PatchFlags 和 Block Tree,只对动态节点进行 diff,并在列表更新时通过最长递增子序列算法,保证 DOM 移动次数最少,因此性能和稳定性都更好。


高频追问(你一定会被问)

Q1:为什么 Vue 3 一定要用 key?

👉 LIS 必须依赖稳定 key 才能算出"最少移动"

Q2:Vue 3 diff 还需要递归吗?

👉 需要,但只在 Block 内的动态节点

Q3:Vue 3 为什么更快?

👉 不是算法更快,是 diff 的节点更少

相关推荐
miofly几秒前
GitHub 今日推荐|floorplan:AI 读代码自动画交互式架构地图
javascript·开源·github
拖孩8 分钟前
AI 帮我写的小程序上线 44 天:36 个人进了收银台,8 个人付钱
前端·后端·微信小程序
java1234_小锋15 分钟前
【技术专题】CSS3 网页技术 - CSS3 视觉增强
前端·css·css3
Dovis(誓平步青云)25 分钟前
拖动关键帧角色就抽动,动画编辑器怎样补齐中间状态
开发语言·前端·javascript·机器学习·编辑器
lpfasd12333 分钟前
pywebview与Electron
前端·javascript·electron
行走的陀螺仪41 分钟前
Claude Code 从入门到实战(一):安装、登录与第一个Vue项目
前端·javascript·vue.js
梦曦i1 小时前
0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧
前端·uni-app x
vipxieliang1 小时前
解构赋值与展开运算符:现代 JS 提效技巧
javascript
Amos_Web1 小时前
Rspack 源码解析(三十四):rspack_hook 与宏系统如何用过程宏生成异步 Hook 与插件
前端
恋猫de小郭1 小时前
感人,Flutter 居然有了一个超实用提案,期待落地
android·前端·flutter