React17 - domDiff,是新的jsx与老的fiber树对比生成新的fiber链表的过程
- 同级节点对比,Dom节点跨层级移动,则React不会复用
- 不同类型元素产出不同结构,销毁老结构,创建新结构
- 可以通过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 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素
不能用index作为key的原因?
index会变动,将index作为key,则每次都是01234,无法辨别是否变动