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

posted @ 2025-03-09 21:53  我是格鲁特  阅读(85)  评论(0)    收藏  举报