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

相关推荐
东方小月22 分钟前
从零开发一个 Coding Agent(七):实现纯文本 Agent Loop
前端·人工智能
大家的林语冰23 分钟前
👉 尤雨溪再次成立新公司,同时官宣 Pinia 4 正式发布!
前端·javascript·vue.js
浮生望26 分钟前
React useRef 深度解析:从DOM操作到Web Worker多线程协作
前端
浮生望32 分钟前
React Router v7 实战全景:路由配置、嵌套路由、鉴权守卫与懒加载完整指南
前端
用户9385156350734 分钟前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战(二)
前端·javascript·typescript
雪隐1 小时前
个人电脑玩AI-16让5060 Ti给你打工——MiniMax H3 提速实录:从"泡杯茶等视频"到"视频等你",一张 5060 Ti 的自我修养
前端·人工智能·后端
FungLeo1 小时前
Flutter Web 中文字体困境与渲染器选择:CanvasKit vs HTML renderer 实战
前端·flutter·html
敲代码的玉米C2 小时前
我修的那个 bug,制造了另一个 bug
前端·人工智能·架构
gis开发之家2 小时前
《Vue3 从入门到大神50篇》Vue3 源码详解(二十):生命周期钩子源码解析 —— onMounted / onUpdated 如何实现?
前端·javascript·前端框架·vue3·vue3源码
Narrastory2 小时前
我用 Claude Code 写代码不到 2 小时,却花了 3 天做完这个软件—Vibe Coding 的正确姿势,是设计不是生成
前端·人工智能·github