Fiber的diff 顺序

591 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

diff 策略

算法复杂度O(n)

  1. 同级比较,Web UI 中 DOM 节点跨层级的移动操作特别少,可以忽略不计。
  2. 拥有不同类型的两个组件将会生成不同的树形结构。 例如:div->p, CompA->CompB
  3. 开发者可以通过 key prop 来暗示哪些子元素在不同的渲染下能保持稳定;

diff过程

比对两个虚拟dom时会有三种操作:删除、替换和更新

vnode是现在的虚拟dom,newVnode是新虚拟dom。

  • 删除:newVnode不存在时
  • 替换:vnode和newVnode类型不同或key不同时
  • 更新:有相同类型和key但vnode和newVnode不同时

在实践中也证明这三个前提策略是合理且准确的,它保证了整体界面构建的性能。

Fiber diff策略

rootFiber开始向下深度优先遍历。为遍历到的每个Fiber节点调用beginWork方法 (opens new window)。方法

该方法会根据传入的Fiber节点创建子Fiber节点,并将这两个Fiber节点连接起来。

当遍历到叶子节点(即没有子组件的组件)时就会调用completeWork (opens new window)处理Fiber节点

当某个Fiber节点执行完completeWork,如果其存在兄弟Fiber节点(即fiber.sibling !== null),会进入其兄弟Fiber调用beginWork方法

如果不存在兄弟Fiber,会进入父级Fiber会调用completeWork方法

用以下例子讲清楚Fiber 层级对比策略

graph TD
A --> B -->D
B --> E
A --> C
A --> H

以上为构建的dom 树,

  1. 会从根节点A向下深度优先遍历,因为A.child(dom 节点里的第一个子节点) = B,对B做 completeWork
  2. B.child = D , 对D做 completeWork
  3. 因为D不存在子节点,此时要找B的兄弟节点 B.sbling -> C, 对C做 completeWork
  4. 因为C不存在子节点,此时找C的兄弟节点C.sbling -> H, 对H做 completeWork
  5. 因为H 既不存在子节点,也不存在兄弟节点,会找其父节点,此时找到C.return -> A