react是如何diff的
React 的 Diff 算法原理
React 的 Diff 算法基于两个核心假设:
- 相同类型的组件生成相似的树结构:如果两个组件的类型相同,它们的 DOM 结构通常也相似。
- 通过唯一 key 标识同级元素:在同级元素中,通过唯一的
key可以更高效地识别哪些元素需要更新、移动或删除。
Diff 算法的比较策略
React 的 Diff 算法采用分层比较策略,只对同一层级的节点进行比较,避免跨层级的复杂比较。具体分为以下几步:
-
逐层比较:从根节点开始,递归比较子节点,但不会跨层级比较。如果发现节点类型不同,React 会直接销毁旧节点及其子树,并重建新节点。
-
列表节点的 key 优化:对于列表节点(如
Array.map生成的子元素),React 依赖key来判断哪些节点可以复用。如果没有key,React 会按顺序比较,可能导致性能下降。
-
节点类型相同时的处理:如果节点类型相同,React 会更新节点的属性(如
className、style等),而不会重新创建节点。对于组件节点,会触发组件的更新生命周期(如componentDidUpdate)。
Diff 算法的优化手段
-
跳过子树比较:如果组件的
shouldComponentUpdate返回false,React 会跳过该组件及其子树的 Diff 过程。 -
批量更新:React 会将多次状态更新合并为一次 Diff 和渲染,减少不必要的计算。

-
复用 DOM 节点:通过
key标识,React 可以复用已有的 DOM 节点,仅更新变化的属性,而不是重新创建节点。
代码示例
以下是一个简单的列表 Diff 示例,展示了 key 的重要性:
// 没有 key 的情况(性能较差)
const items = ['A', 'B', 'C'];
const listWithoutKey = items.map(item => <li>{item}</li>);
// 有 key 的情况(性能优化)
const listWithKey = items.map((item, index) => <li key={index}>{item}</li>);
数学表达
Diff 算法的时间复杂度从 O(n³) 优化到 O(n),主要得益于以下策略:
- 分层比较:避免跨层级比较,复杂度降为 O(n)。
- key 标识:通过唯一 key 快速匹配节点,避免遍历所有子节点。
React 的 Diff 算法通过以上策略实现了高效的 DOM 更新,避免了不必要的渲染开销。






