React Fiber的调度算法你了解多少呢?

React Fiber 的调度算法是 React 架构中最核心的部分之一,它是为了支持 可中断、可恢复、可优先级排序的更新 而设计的调度系统。


🧠 React Fiber 调度算法的核心理念

React Fiber 的调度算法是一个 "cooperative scheduling"(合作调度) 模型,它让渲染过程变成了可中断的工作单元,从而可以让浏览器在必要时打断 React,让出主线程以响应用户交互。


🧩 Fiber 架构基本概念

Fiber 是什么?

  • React Fiber 是一个工作单元(Work Unit)
  • 每个 Fiber 节点对应一个组件实例
  • 每次更新都是在构建一棵新的 Fiber 树

Fiber 树的遍历过程分为两个阶段:

  1. render 阶段(工作阶段) :构建新的 Fiber 树,生成副作用列表(effect list)。此阶段是可中断的
  2. 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)

  • 在组件中调用 setStatedispatch 时触发
  • 把该 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 包括三个子阶段:

  1. beforeMutation(如生命周期 getSnapshotBeforeUpdate)
  2. mutation(如 DOM 插入、删除)
  3. 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 分帧处理
支持优先级调度 用户交互优先于动画、过渡等
渲染暂停与恢复 比如页面在后台不渲染,返回再恢复

相关推荐
牧羊狼的狼2 小时前
React 中的 HOC 和 Hooks
前端·javascript·react.js·hooks·高阶组件·hoc
知识分享小能手4 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
魔云连洲4 小时前
深入解析:Vue与React的异步批处理更新机制
前端·vue.js·react.js
mCell4 小时前
JavaScript 的多线程能力:Worker
前端·javascript·浏览器
超级无敌攻城狮6 小时前
3 分钟学会!波浪文字动画超详细教程,从 0 到 1 实现「思考中 / 加载中」高级效果
前端
excel7 小时前
用 TensorFlow.js Node 实现猫图像识别(教学版逐步分解)
前端
gnip7 小时前
JavaScript事件流
前端·javascript
赵得C7 小时前
【前端技巧】Element Table 列标题如何优雅添加 Tooltip 提示?
前端·elementui·vue·table组件
wow_DG7 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(一):响应式原理
前端·javascript·vue.js
weixin_456904278 小时前
UserManagement.vue和Profile.vue详细解释
前端·javascript·vue.js