← 返回目录

第 28 卷

第 28 / 28 卷日期:

四十、React 18 引入了新的协调器(Concurrent Mode)。请从源码角度

解释 Concurrent Mode 的工作原理是什么?

注:React 18 中,“Concurrent Mode”(并发模式)已不再是明确的“模式”,而是升级为「并发渲染能力」(Concurrent Rendering),通过底层协调器(Reconciler)的重构实现,核心依赖

「Scheduler(调度器)」「Fiber 架构」「Lane 优先级模型」三大核心模块。从源码角度,其工作原理可拆解为“优先级调度-可中断协调-提交确认”三个核心阶段,以下结合源码核心逻辑展开说明:

核心前提:并发渲染能力默认不开启,需通过 createRoot 启用,本质是让协调器具备“中断、暂停、恢复、放弃渲染”的能力,优先处理高优先级任务。

1. 源码核心依赖模块

并发渲染的实现依赖 React 源码中三个核心模块的协同工作:

•(1)Scheduler(调度器):源码位置 react-scheduler,负责任务的优先级排序、时间切

片管理(默认 16ms),判断任务是否需要中断;

•(2)Reconciler(协调器):源码位置 react-reconciler,基于 Fiber 架构,负责组件树的

遍历(可中断)、Diff 算法执行、标记更新类型(effectTag);

•(3)Lane 模型(优先级模型):源码中通过二进制位表示任务优先级(如 ImmediateLane 最

高,IdleLane 最低),用于标记每个更新任务的优先级,决定任务的执行顺序。

2. 工作原理核心流程(源码视角)

(1)阶段一:任务调度与优先级标记(Scheduler + Lane 模型)

当触发状态更新(如 setState、useState 更新)时,React 源码会执行以下步骤:

  1. 创建更新对象(Update):封装更新的状态值、回调函数等信息;
  2. 通过 Lane 模型为更新任务分配优先级:根据更新类型(如用户输入为高优先级,数据加载为低优

先级),从 Lane 优先级列表中分配对应的 Lane(二进制位);

  1. 将更新对象加入对应 Fiber 节点的更新队列(updateQueue);
  2. 调用 Scheduler 的 scheduleCallback 方法,将协调任务(Reconciliation)加入调度队列,

等待执行。

源码关键逻辑:Lane 模型通过二进制位运算高效判断任务优先级,例如高优先级任务的 Lane 会覆盖低优先级任务,确保高优先级任务优先执行。

(2)阶段二:可中断协调(Reconciler + Fiber 架构)

调度器触发协调任务后,协调器基于 Fiber 架构开始遍历组件树(深度优先),此过程可被中断,核心源码逻辑是 workLoop 函数(可中断的循环遍历):

4let current = workInProgress; // 当前正在处理的 Fiber 节点 5while (current !== null && !shouldYield()) { // shouldYield() 由 Scheduler 提

供,判断是否需要中断

6//处理当前Fiber节点(执行Diff、标记effectTag)
7performUnitOfWork(current);
8//移动到下一个Fiber节点(基于Fiber链表:child > sibling > return)
9current = getNextUnitOfWork(current);
10}
11//若任务未完成(current !== null),则再次调度,等待恢复执行
12if (current !== null) {
13scheduleCallback(performConcurrentWorkOnRoot.bind(null, root, lanes));
14}
15 }

关键细节:

• 可中断判断: shouldYield() 函数由 Scheduler 提供,判断当前时间切片是否用尽(默认

16ms)或是否有更高优先级任务插入;若需要中断,立即停止遍历,保存当前 Fiber 节点(workInProgress)的状态;

• 任务恢复:当高优先级任务执行完成或时间切片重新分配后,调度器会再次调用 workLoop,从

上次中断的 Fiber 节点继续遍历;

• 任务放弃:若在中断期间,有更高优先级的更新任务覆盖了当前任务(通过 Lane 模型判断),则

直接放弃当前未完成的协调任务,重新开始高优先级任务的协调。

(3)阶段三:提交阶段(不可中断,Renderer 参与)

当协调阶段完成(所有 Fiber 节点遍历完成,Diff 对比结束,标记完所有 effectTag),React 会进入提交阶段(Commit),此阶段不可中断(避免 DOM 状态不一致),核心源码逻辑是 commitRoot

函数:

  1. 执行前置清理逻辑:如调用组件的 getSnapshotBeforeUpdate 生命周期;
  2. 执行 DOM 操作:根据 Fiber 节点的 effectTag(如插入、更新、删除),批量执行真实 DOM 操

作;

  1. 执行后置逻辑:如调用组件的 componentDidMount / componentDidUpdate 生命周期、

useEffect 回调、更新任务的回调函数;

  1. 切换 Fiber 树:将 workInProgress 树(协调阶段构建的新树)切换为 current 树(当前渲染的

树),完成渲染更新。

•(1)时间切片(Time Slicing):Scheduler 基于 requestIdleCallback 模拟实现时间切

片(兼容不支持该 API 的浏览器),确保每次协调任务的执行时间不超过 16ms(对应 60fps 的刷新率),避免长时间占用主线程;

•(2)优先级抢占:通过 Lane 模型标记任务优先级,高优先级任务可在低优先级任务执行过程

中“插队”(Scheduler 触发中断),低优先级任务需等待高优先级任务完成后才能恢复执行,确保用户输入、动画等关键操作的响应速度。

4. 源码层面的关键设计:双缓存 Fiber 树

并发渲染依赖 Fiber 架构的“双缓存”设计(源码中通过 current 和 workInProgress 两个 Fiber 树实现):

  • current 树:对应当前页面渲染的 DOM 结构,不可修改;
  • workInProgress 树:协调阶段构建的新树,可中断修改,包含最新的组件状态和 DOM 变化。

优势:协调阶段的中断/修改不会影响 current 树,确保页面渲染状态稳定;提交阶段仅需切换两棵树的引用,即可完成 DOM 更新,高效且安全。

5. 总结(源码视角)

React 18 的并发渲染(原 Concurrent Mode)本质是通过「Scheduler 调度优先级任务」

「Reconciler 执行可中断协调」「Lane 模型标记优先级」「双缓存 Fiber 树保障稳定性」的协同工作,实现“高优先级任务优先执行,低优先级任务可中断等待”的渲染能力。从源码来看,核心是对

协调器(Reconciler)的重构,通过 workLoop 可中断循环、 shouldYield 中断判断、Lane 优先级标记等逻辑,让 React 能够灵活控制渲染流程,避免主线程阻塞,最终提升应用的响应速度和用

户体验。

(注:文档部分内容可能由 AI 生成)

全站分卷索引 · 28 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷