react-domDiff

150 阅读2分钟

React17 - domDiff,是新的jsx与老的fiber树对比生成新的fiber链表的过程

  1. 同级节点对比,Dom节点跨层级移动,则React不会复用
  2. 不同类型元素产出不同结构,销毁老结构,创建新结构
  3. 可以通过key标示移动的元素,如果节点没有key,则可以认为是索引

单节点对比-新元素只有一个

  • key和type都相同,才能复用,子元素不一样更新即可
  • key不一样,则把旧的删除,继续向下对比
  • key相同,type不同,则不进行后续对比,把老的全部删除,插入新的
  • 新旧一样,则复用老的DOM元素和Fiber对象

新节点有多个,需要经过两轮遍历

  • 第一轮:属性和类型type的更新(因为情况较多,所以放在第一轮)
  • 第二轮:新增、移动、删除
  • 如果第一轮遍历遇到key不一样,则立刻跳出第一轮循环,说明有位置变化,
  • 第二轮会根据lastPlaceIndex进行移动的标记,大于新节点索引,则新节点移动
  • 新高位不移动,新低位移动
  • 第二轮对比完毕后,将多余的节点删除
  • 顺序:删除-〉更新-〉移动-〉插入
  • 二进制: 8 4 2
一定要写key的原因?
1、提高domdiff的性能,有key对比则大部分是移动,无key对比则大部分是删除
2、当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素

参考: www.zhihu.com/question/61…

不能用index作为key的原因?
index会变动,将index作为key,则每次都是01234,无法辨别是否变动