Zhi-Ling

You can do Everything you want

0%

Fiber-Architecture

Brief Intro: New Architecture to React solve some remaining problems, it’s working process and every part of stage has completely change in fiber

Render 阶段

  • 在内存中执行,工作结束后通知 renderer 进行相应的 DOM 操作;
  • 开始于 performSyncWorkOnRoot 或 performConcurrentWorkOnRoot
1
2
3
4
5
function workLoopSync() {
while (workInProgress !== null) {
performUnitOfWork(workInProgress);
}
}
1
2
3
4
5
function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield) {
performUnitOfWork(workInProgress);
}
}
  • performUnitOfWork 会创建 Fiber 节点并赋值给 workInProgress,并将 workInProgress 和已创建的 Fiber 连接起来构成 Fiber 树

PerformUnitOfWork

递阶段

  1. 从 rootFiber 开始向下深度优先遍历,为每个 Fiber 节点调用 beginWork 方法
  2. beginWork 跟据传入的 fiber 节点创建子fiber节点,并将两个 fiber 节点连接起来
  3. 遍历到叶子节点的时候,进入” 归 “阶段

归阶段

  1. 调用 completeWork 处理 fiber 节点
  2. 如果存在兄弟节点,即 fiber.sibling!==null,则开始进入兄弟节点的递阶段,如果不存在,则进入父级 fiber 的归阶段
  3. 一直归到 rootFiber,则完成 render 阶段的工作

BeginWork(递阶段)

mount:首次渲染,没有 current,即 current===null。跟据 fiber.tag 不同,创建不同的 fiber 节点
update:current !== null,创建新的 fiber 树,如果存在同样的节点,就可以复用,不存在的话就生成新的 fiber 节点,生成结束后把 current 的指针指向 workInporgress 树,之前的指针断开引用,内存回收
reconcilerChildren
mount:创建新的子fiber节点
update:将当前的组件和上次更新的组件进行对应 fiber 节点比较,即 Diff 算法,跟据比较结果生成新的 fiber 节点;
effectTag:执行 dom 操作的具体类型保存在 fiber。effectTag 中

CompleteWork(归阶段)

hostComponent:原生 DOM 对应的 fiber 节点

mount

  1. 为 fiber 节点生成对应的 DOM 节点
  2. 将子孙的 fiber 节点插入生成的 DOM 节点中
  3. 处理传入的 props
  4. appendAllChildren
    1. 在 commit 阶段一次插入整颗 dom 树
    2. 每次调用 appendAllChildren 时会将已生成的子孙 DOM 节点插入当前生成的 DOM 节点下

update

  1. 处理 props:onClick,onChange 等回调函数注册;style prop;DANGEROUSLY_SET;children prop
  2. 主要调用 updateHostComponent 方法,在该方法内部,处理完成后的 props 被赋值给 workInProgress.updateQueue

effectList

  1. completeWork 的前置函数 completeUnitOfWork 中,每个执行完 completeWork 且存在 effectTag 的 fiber 节点会被保存在 effectList 的单向链表中
  2. 第一个 fiber 节点保存在 fiber.firstEffect,最后一个保存在 fiber.lastEffect 中
  3. commit 阶段只需要遍历 effectList 即可执行所有的 effect
  4. performSyncWorkOnRoot 函数中的 fiberRootNode 传递给 commitRoot,开启 commit 阶段

Commit 阶段

before mutation(执行 DOM 操作前)

  • 遍历 effectList,并调用 commitBeforMutationEffects 函数

commitBeforeMutationEffects

  1. 处理 DOM 节点渲染 / 删除后的 autoFocus、blur 逻辑
  2. 调用 getSnapshotBeforeUpdate 生命周期钩子
  3. 异步调度 useEffect:防止同步渲染时阻塞浏览器渲染

mutation(执行 DOM 操作)

  • 遍历 effectList,执行 commitMutationEffects

commitMutationEffects

  1. 根据 ContentReset effectTag 重置文字节点
  2. 更新 ref
  3. 根据 effectTag 分别调用不同函数处理 fiber,其中 effectTag 包括 (Placement | Update | Deletion | Hydrating)

layout(执行 DOM 操作后)

  • 遍历 effectList,执行 commitLayoutEffects

commitLayoutEffects

  1. commitLayoutEffectOnFiber(调用生命周期钩子和 hook 相关操作)
  2. commitAttachRef(赋值 ref)
  3. 跟据 effectTag 调用不同的处理函数处理 fiber 并更新 ref

Welcome to my other publishing channels