一句话总概括
响应式负责【找到谁要更新】,
编译优化负责【缩小要更新的范围】,
Diff 负责【用最少代价更新 DOM】。
三者配合,让 Vue3 实现了"精准、快速、无阻塞"的更新。
完整工作流程(从数据变化到视图更新)
1. 响应式系统:精准定位"哪些组件需要重新渲染"
- 你修改响应式数据(ref/reactive)
- 触发
set→trigger - 找到依赖这个数据的 effect(组件渲染副作用)
- 把组件加入异步更新队列
它的作用只有一个:
确定最小更新范围,不让无关组件参与渲染。
响应式 = 精准制导,只炸目标,不炸全图
2. 组件重新渲染:编译优化上场,生成"最优 VNode"
组件开始执行 render 生成 VNode,
编译优化在这一步大幅降低运行时开销:
-
静态提升(hoistStatic)
静态节点已经被提升,渲染时直接复用,不创建新 VNode。
-
PatchFlag 标记动态内容
编译器提前给每个动态节点打上类型:TEXT / CLASS / STYLE / PROPS 等。
-
Block Tree
把所有动态节点打平收集到一个数组里,
后续 Diff 只遍历这个数组,不遍历整棵树。 -
cacheHandler 缓存事件
内联函数复用,避免不必要更新。
经过编译优化后:
VNode 树已经被"预处理"过,动态就是动态,静态就是静态,清清楚楚。
编译优化 = 提前做好标记,让 Diff 别瞎找
3. Diff 阶段:用最小 DOM 操作完成更新
拿到新旧 VNode 后,进入 patch 对比:
- 只对比 Block Tree 里的动态节点数组
- 根据 PatchFlag 只对比对应类型的内容
- 只变文本 → 只更文本
- 只变 class → 只更 class
- 同层级节点对比,使用 双端比较 + 最长递增子序列 LIS
- 最大化复用 DOM
- 最小化移动次数
最终输出最少、最轻量的 DOM 操作。
Diff = 用理论最优的方式操作 DOM
三者配合的最终效果(最精华)
- 响应式:从根上减少需要渲染的组件
- 编译优化:从结构上减少需要 Diff 的节点
- Diff 算法:从操作上减少真实 DOM 修改
三者叠加 =
更新范围最小 → 对比量最小 → DOM 操作最少
这就是 Vue3 为什么极快、极稳、不依赖 Fiber。
面试满分口述版(直接背)
- 响应式系统负责依赖收集,数据变化时精准找到需要更新的组件,避免全量渲染。
- 组件渲染时,编译优化通过静态提升、PatchFlag、Block Tree 等,把动态节点标记并打平,大幅减少运行时 Diff 成本。
- 最后 Diff 算法基于标记信息做靶向对比,并通过最长递增子序列实现 DOM 最小移动。
- 三者配合,让 Vue3 实现了更新范围最小、对比最快、DOM 操作最少的同步更新模型,不需要 Fiber 也能保持高性能。
一句封神总结
响应式决定"更不更",
编译优化决定"哪部分更",
Diff 决定"怎么更最便宜"。