React Fiber 的调度算法是 React 架构中最核心的部分之一,它是为了支持 可中断、可恢复、可优先级排序的更新 而设计的调度系统。
🧠 React Fiber 调度算法的核心理念
React Fiber 的调度算法是一个 "cooperative scheduling"(合作调度) 模型,它让渲染过程变成了可中断的工作单元,从而可以让浏览器在必要时打断 React,让出主线程以响应用户交互。
🧩 Fiber 架构基本概念
Fiber 是什么?
- React Fiber 是一个工作单元(Work Unit)
- 每个 Fiber 节点对应一个组件实例
- 每次更新都是在构建一棵新的 Fiber 树
Fiber 树的遍历过程分为两个阶段:
- render 阶段(工作阶段) :构建新的 Fiber 树,生成副作用列表(effect list)。此阶段是可中断的。
- commit 阶段(提交阶段) :执行副作用,如 DOM 操作。此阶段是同步的、不可中断的。
🔁 调度算法核心流程
一、任务调度入口
scss
ReactDOM.createRoot(container).render(<App />);
每次更新(比如 setState、useState)都会被封装为一个**任务(Task)**加入任务队列,由调度器统一处理。
二、任务优先级:Lane 模型(React 18 引入)
-
**Lane(车道)**是 Fiber 用来标识任务优先级的一种机制。
-
不同更新对应不同的 Lane,如:
- SyncLane(同步)
- InputContinuousLane(连续用户输入)
- DefaultLane(默认)
- TransitionLane(过渡动画)
- IdleLane(空闲)
多个 Lane 可以组合在一起,形成并发调度策略
三、工作循环(Work Loop)
1. scheduleUpdateOnFiber(fiber)
- 在组件中调用
setState
或dispatch
时触发 - 把该 Fiber 节点所在的根节点标记为"有更新"
- 提交到调度器进行调度(例如调用
ensureRootIsScheduled
)
2. performConcurrentWorkOnRoot(root)
- 检查当前任务是否过期
- 执行 render 阶段的 work loop
3. workLoopConcurrent()
- 类似一个
while
循环:遍历 Fiber 树,执行每个节点的工作单元 - 每次循环都会检查浏览器是否有更高优先级任务需要处理
ini
while (workInProgress !== null && !shouldYield()) {
workInProgress = performUnitOfWork(workInProgress);
}
shouldYield()
是通过scheduler
提供的requestIdleCallback
/MessageChannel
模拟的,用于判断是否中断。
四、执行每个单元:performUnitOfWork(fiber)
ini
function performUnitOfWork(fiber) {
const next = beginWork(fiber);
if (next === null) {
completeUnitOfWork(fiber);
} else {
return next;
}
}
beginWork
:构建子节点(虚拟 DOM)completeUnitOfWork
:回溯并收集副作用(effect list)
这两个函数递归遍历整棵树(DFS)。
五、render 完成后 → 进入 commit 阶段
当所有 Fiber 节点遍历完成,进入同步的 commit 阶段:
scss
commitRoot(root);
commit 包括三个子阶段:
- beforeMutation(如生命周期 getSnapshotBeforeUpdate)
- mutation(如 DOM 插入、删除)
- layout(如 useLayoutEffect)
⚙️ Scheduler 调度器简介
React 的调度器(scheduler
包)是 React 自己实现的一套任务优先队列系统,模拟浏览器空闲时间运行任务。
主要功能:
- 时间分片(Time Slicing)
- 任意任务优先级调度(优先处理重要更新)
- 模拟浏览器调度行为
使用:
scss
unstable_scheduleCallback(priorityLevel, callback);
🪜 优先级分类(Lane 与 Scheduler 优先级对应关系)
Lane | 示例 | 对应 Scheduler 优先级 |
---|---|---|
SyncLane | setState in click |
Immediate |
InputContinuousLane | 输入 | UserBlocking |
DefaultLane | 默认更新 | Normal |
TransitionLane | startTransition |
Low |
IdleLane | 无时间限制的更新 | Idle |
🎯 总结流程图(简化版)
scss
用户操作触发更新(setState)
↓
scheduleUpdateOnFiber
↓
requestIdleCallback / MessageChannel
↓
performConcurrentWorkOnRoot
↓
render阶段 (Fiber 树遍历) [可中断]
↓
commit阶段 (DOM 更新) [同步执行]
✅ Fiber 调度算法的优势
优点 | 说明 |
---|---|
可中断更新 | 避免主线程卡顿 |
可分片执行 | 利用 requestIdleCallback / MessageChannel 分帧处理 |
支持优先级调度 | 用户交互优先于动画、过渡等 |
渲染暂停与恢复 | 比如页面在后台不渲染,返回再恢复 |