一、主流程总览
scss
┌──────────────────────────────────────────────────────────────┐
│ 挂载:createContainer → createFiberRoot → createHostRootFiber│
│ 更新:updateContainer → createUpdate → enqueueUpdate │
│ → scheduleUpdateOnFiber │
└──────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────┐
│ ensureRootIsScheduled │ ← ReactFiberRootScheduler
│ (接入 Scheduler) │
└───────────────────────┘
│
┌───────────▼───────────------------------┐
│ performConcurrentWorkOnRoot │ ← 启动并发渲染
│ (由 Scheduler 回调) │
└───────────┬───────────------------------┘
│
┌───────────▼───────────┐
│ renderRootConcurrent │ ← 并发渲染循环(可中断)
│ 或 renderRootSync │ ← 同步渲染循环(不可中断,用于 LegacyRoot)
└───────────┬───────────┘
│
┌──────────▼──────────┐
│ prepareFreshStack │ ← 创建 workInProgress 树
└──────────┬──────────┘
│
┌─────────────────▼─────────────────┐
│ workLoopConcurrent / workLoopSync │ ← 逐个 fiber 执行
│ ┌─────────────────────────────┐ │
│ │ performUnitOfWork(fiber) │ │ ← 执行 beginWork,若无子节点则 completeUnitOfWork
│ │ ├─ beginWork() [递] │ │
│ │ │ → 返回 child fiber │ │
│ │ └─ completeUnitOfWork()[归] │ │ ← 归阶段:sibling → 父 completeWork
│ │ → completeWork() │ │
│ └─────────────────────────────┘ │
│ 并发模式: shouldYield() 控制中断 │
└─────────────────┬─────────────────┘
│
┌───────────▼───────────┐
│ finishConcurrentRender│
│ → completeRoot │ ← 渲染完成,提交前准备
└───────────┬───────────┘
│
┌───────────▼───────────┐
│ commitRoot │ ← 三阶段提交
│ ├─ commitBeforeMutation │ Snapshot
│ ├─ commitMutation │ DOM 操作
│ └─ commitLayout │ useLayoutEffect
└───────────────────────┘
二、挂载(createRoot → 首次渲染)
scss
createContainer(container, ConcurrentRoot, ...)
→ createFiberRoot(...)
→ createHostRootFiber(ConcurrentRoot) → Fiber(HostRoot)
→ initializeUpdateQueue(fiber)
→ return FiberRoot
updateContainer(<App />, root, null, null)
→ requestUpdateLane → SyncLane
→ createUpdate(lane) → {payload: {element: <App/>}}
→ enqueueUpdate(rootFiber, update, lane)
→ scheduleUpdateOnFiber(root, rootFiber, lane)
→ markRootUpdated(root, lane)
→ ensureRootIsScheduled(root)
→ Scheduler.scheduleCallback(priority, performConcurrentWorkOnRoot)
三、渲染循环(renderRootConcurrent)
scss
renderRootConcurrent(root, lanes)
→ prepareFreshStack(root, lanes)
→ createWorkInProgress(root.current, null) → 新的 workInProgress 根
→ workInProgress = root.current.alternate
→ workLoopConcurrent():
while (workInProgress !== null && !shouldYield()) {
performUnitOfWork(workInProgress)
}
performUnitOfWork(fiber):
next = beginWork(current, fiber, renderLanes) // 递
if (next === null):
completeUnitOfWork(fiber) // 归
else:
workInProgress = next // 继续深入
completeUnitOfWork(fiber):
do:
completeWork(current, fiber, renderLanes) // 完成当前
if (sibling): workInProgress = sibling; return
fiber = return // 回到父节点
while (fiber !== null)
递阶段
作用:根据 fiber.tag 分发到不同处理函数,返回子 fiber。
scss
beginWork(current, workInProgress, renderLanes)
↓
switch (workInProgress.tag):
├── FunctionComponent → updateFunctionComponent()
│ → renderWithHooks() → 执行函数体 → reconcileChildren()
├── ClassComponent → updateClassComponent()
│ → 实例化/更新 → 调用生命周期 → reconcileChildren()
├── HostRoot → updateHostRoot()
│ → processUpdateQueue() → reconcileChildren()
├── HostComponent → updateHostComponent()
│ → 处理 DOM 属性 → reconcileChildren()
├── HostText → updateHostText()
├── Fragment → updateFragment()
├── ContextProvider → updateContextProvider()
│ → pushProvider() → propagateContextChange()
├── ContextConsumer → updateContextConsumer()
│ → readContext() → 订阅变化
├── SuspenseComponent → updateSuspenseComponent()
├── ForwardRef → updateForwardRef()
│ → renderWithHooks() → reconcileChildren()
├── MemoComponent → updateMemoComponent()
│ → shallowEqual 比较 props → 跳过或深入
├── OffscreenComponent → updateOffscreenComponent()
└── ActivityComponent → updateActivityComponent()
↓
若返回 null → 进入 completeUnitOfWork
若返回 fiber → 继续 workLoop(深度优先遍历)
bailout 优化 :当 props/state/context 未变化且 lanes 不匹配时,bailoutOnAlreadyFinishedWork() 跳过子树。
归阶段
作用:自底向上完成 fiber 处理。为 HostComponent 创建/更新 DOM 实例。
scss
completeWork(current, workInProgress, renderLanes)
↓
switch (workInProgress.tag):
├── HostComponent →
│ mount: createInstance() → appendAllChildren() → 设置属性
│ update: diffProperties() → 记录 updatePayload
├── HostText → createTextInstance() / 更新文本
├── HostRoot → 完成根节点
├── HostSingleton → body/html/head 特殊处理
├── ContextProvider → popProvider() 回滚上下文
├── SuspenseComponent → 决定挂起/恢复
├── OffscreenComponent → 处理隐藏/显示
└── ViewTransitionComponent → ViewTransition 处理
↓
bubbleProperties(workInProgress)
→ subtreeFlags |= child.subtreeFlags | child.flags
→ childLanes = mergeLanes(child.childLanes, child.lanes)
bubbleProperties:将子树的 flags 和 lanes 冒泡到父 fiber,使根能汇总所有副作用。
四、提交阶段(commitRoot)
作用:将渲染结果提交到 DOM。分三个子阶段执行。
scss
commitRoot(root, finishedWork, ...)
→ 执行全局副作用通知
→ flushPendingEffects() // 先处理残留的 effect
→ 设置 pendingEffectsRemainingLanes
→ 根据 status 决定是否提交
commitRootImpl(root, ...)
→ commitBeforeMutationEffects(finishedWork)
→ Snapshot flag: getSnapshotBeforeUpdate
→ 调度 Passive effects(setTimeout/flushPassiveEffects)
→ commitMutationEffects(finishedWork, root)
→ Placement: DOM 插入
→ Update: DOM 属性更新
→ Ref: 更新/清理 ref
→ ChildDeletion: 删除 DOM + 卸载 effects
→ commitAfterMutationEffects(root)
→ commitLayoutEffects(finishedWork, root)
→ useLayoutEffect 挂载/更新
→ componentDidMount/Update
→ 赋值 ref
→ flushPassiveEffects() // 异步执行 useEffect
Mutation 阶段
commitMutationEffects 遍历 finishedWork.flags
scss
Placement → commitPlacement() → appendChild / insertBefore (DOM 插入)
Update → commitUpdate() → diffProperties 写入 DOM
ChildDeletion → commitDeletion() → 卸载 effects,移除 DOM
Ref → commitDetachRef() / commitAttachRef()
Hydrating → commitHydratedDOM()
Visibility → Offscreen 隐藏/显示
ContentReset → resetTextContent()
Layout 阶段
sql
commitLayoutEffects(finishedWork)
→ 遍历 fiber 树
→ Callback flag → commitCallbacks(componentDidMount/Update 回调)
→ Ref flag → commitAttachRef(挂载 ref)
→ Update flag → commitLayoutEffectOnFiber(执行 useLayoutEffect)