react虚拟dom是什么?是如何提升性能的
虚拟dom是react的核心概念,它使用js对象来反应真实dom的结构。
当组件的状态变更后,react会计算出新的虚拟dom树,并跟前一次的虚拟dom树进行对比,找出差异(也就是需要更新的部分),最后仅将这些差异应用到真实 DOM 中。通过这种方式,React 避免了对真实 DOM 的频繁操作,从而提高了性能。
ReactDom Diff算法核心思想
核心策略一:假设树节点不会跨层级移动,因此只做同层比较,不跨层对比
![]()

如果节点层级发生变化,直接销毁原来的 DOM,重新创建。
![]()
如上图所示,当A需要移动到D下面时,react会先删除A,然后再到D节点中创建A
核心策略二:列表 diff,先比较key,再比较类型
使用 key 属性来唯一标识每个节点。key 的作用是帮助 React 判断一个节点是否在新旧列表中相同,从而决定是否 复用、删除 或 插入 节点
基于key的移动算法策略: 只要遍历新列表的时候,老列表的顺序还能顺着走(即索引是递增的),就说明顺序还是对的,不需要移动节点。一旦需要回头,说明老列表里的顺序不满足新列表了,就需要移动

以上图为例,比较过程如下:
| 新集合遍历到的节点 | 在老集合中的索引 | lastPlacedIndex(期望递增) | 是否需要移动 |
|---|---|---|---|
| b | 1 | 1 | 否 |
| a | 0 | 1 | 是 |
| d | 3 | 1 | 否 |
| c | 2 | 3 | 是 |
b→ 老集合索引是1,不动。a→ 老集合索引是0,发现索引不递增(<lastPlacedIndex),触发移动。d→ 老集合索引是3,不动。c→ 老集合索引是2,索引不是递增(应该大于3),触发移动。
// 模拟的新旧节点集合
const oldList = ['a', 'b', 'c', 'd'];
const newList = ['b', 'a', 'd', 'c'];
// 用于存储老集合节点在新集合中的索引
let lastPlacedIndex = -1; // 初始时没有节点被处理过
// 遍历新集合
newList.forEach((newNode, newIndex) => {
// 查找新节点在老集合中的位置
const oldIndex = oldList.indexOf(newNode);
// 判断是否需要移动
if (oldIndex < lastPlacedIndex) {
// 需要移动,因为索引不再递增
console.log(`节点 ${newNode} 需要移动`);
} else {
// 不需要移动
console.log(`节点 ${newNode} 不需要移动`);
}
// 更新 lastPlacedIndex
lastPlacedIndex = Math.max(lastPlacedIndex, oldIndex);
});
核心策略三:key相同时再判断节点烈性
相同类型节点,保留,更新属性;不同类型节点,销毁再创建
如上图:当component D的位置换成了component G 后,即使两者的结构非常类似,也会将D删除再重新创建G


浙公网安备 33010602011771号