Skip to content

Vue 3:虚拟 DOM、diff、优化与 Vue2 / React 对比

一、虚拟 DOM

VNode 用 JS 描述 UI;更新时生成新树,与旧树 diff,再 patch 真实 DOM。

优势

  • 批量最小化 DOM 写入。
  • 抽象渲染后端(Web / 小程序等)。

Vue 3 工作流程补充

  1. 编译器标记动态节点(PatchFlag)。
  2. diff 时跳过纯静态子树。
  3. 列表采用 最长递增子序列(LIS) 减少移动次数。

二、Vue 3 diff 相对 Vue 2

编译期

  • PatchFlags:只比对变化的属性/ children 动态部分。
  • 静态提升(hoistStatic):静态节点提到渲染函数外复用。
  • 事件缓存:避免无谓的函数重建(与编译实现相关)。

运行时列表

  • Vue 2:双端比较
  • Vue 3:预处理两端相同前缀/后缀 + key 映射 + LIS 减少移动。

三、自动优化 vs 手动优化

编译器已做

静态提升、PatchFlag、事件缓存、Tree-shaking 等。

手写侧

  • shallowRef / shallowReactive / markRaw 控制代理深度。
  • 路由与组件懒加载
  • keep-alive 缓存存活实例。
  • computed 缓存计算;watch 监听粒度尽量细。
  • 列表:唯一 key、虚拟滚动、v-memo(Vue 3)等。
  • v-pre / v-cloak:跳过编译、防闪烁。

四、跨框架 diff 对照说明

列表策略

  • Vue 2:双指针四向尝试。
  • Vue 3LIS 最小移动。
  • React:单向扫描 + key Map(不自带 Vue3 那种 LIS 移动最优策略)。

共同点

  • 跨层移动通常视作删除 + 新建。
  • key 都是识别节点身份的核心。

patch 与异步队列

单次响应式 tick 内可能合并多次数据变更,但 patch 递归过程中仍是「对比一段、更新一段」;与「队列合并」解决的是触发次数,不是 patch 内部递归形态。


五、小结

  • 虚拟 DOM 提供可 diff 的中间表示。
  • Vue 3 把大量优化前移到编译期
  • 列表性能:稳定 key + 合理数据结构;极长列表用虚拟化。

下一章:TypeScript·SSR·错误