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 分帧处理
支持优先级调度 用户交互优先于动画、过渡等
渲染暂停与恢复 比如页面在后台不渲染,返回再恢复

相关推荐
小小小小宇6 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊6 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习7 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖7 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖8 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水8 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐8 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06278 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
灿灿121388 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴9 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript