每次面试问到了解 React Diff 算法吗?我都不知道说什么,这次总结一下,该怎么说。
首先我们应该思考为什么要有这么一个东西,也就是它的目的是什么?
目的
React Diff 算法的目的是优化真实 DOM 更新,手段是搞一套虚拟 DOM 树,并对比新旧虚拟 DOM 树的差异,然后只对有虚拟 DOM 树中有差异的地方去更新真实 DOM。
时间复杂度:通过启发式策略(如:同层比较、Key 标识)将传统 $$O(n^3)$$ 复杂度降至 O(n)
三大核心策略
- Tree Diff(树层比较)
- 仅比较同一层级节点,跨层级移动会触发销毁和重建(如:节点从父节点 A 移动到节点 B,视为删除后重建),疑问?假如父节点 A、B 是同层级,那么它们的子节点(A+B)算同一层级吗
- 优化建议:避免频繁跨层级操作,可用 CSS 隐藏代替 DOM 移除
- Component Diff(组件比较)
- 相同类型组件:递归比较子节点,触发更新生命周期(如:componentDidUpdate)
- 不同类型组件:直接销毁旧组件(触发 componentWillUnmount)并创建新组件(触发 componentDidMount)
- Element Diff(元素比较)
- 节点类型不同:直接替换整个节点(如
<div>
变为<span>
) - 节点类型相同:仅更新属性和子节点(如修改 className 或文本内容)
- 节点类型不同:直接替换整个节点(如
Fibber 架构下的优化(React 16+)
- 增量更新与任务拆分
- Diff 过程拆分为可中断的小任务,避免阻塞主线程
- 高优先级更新(如用户交互)可中断低优先级任务
- 更细粒度的协调
- Fiber 节点保存完整上下文,支持更精准的 Diff 和状态复用