React 18 的整体架构设计是在 React 16 引入的 Fiber 架构基础上,通过增强并发渲染能力、优化调度机制和扩展核心 API 实现的重大升级。其核心目标是支持并发渲染、异步可中断式更新 ,让应用在处理复杂计算或大量 UI 更新时仍能保持流畅的用户交互。
一、整体架构设计:三层核心架构 + 并发能力扩展
React 18 的架构可分为应用层、核心层、平台层三大层级,各层级职责明确且协同工作:
┌───────────────── 应用层 ─────────────────┐
│ 组件(函数/类)、Hooks、状态管理 │
│ 新增:并发特性 API(useTransition 等) │
├───────────────── 核心层 ─────────────────┤
│ 调度器(Scheduler):任务优先级与中断控制 │
│ 协调器(Reconciler):Fiber Diff 与更新计划 │
│ 渲染器(Renderer):提交更新与平台渲染 │
├───────────────── 平台层 ─────────────────┤
│ Web(DOM)、Native(React Native)等 │
└──────────────────────────────────────────┘
1. 核心设计理念
- 并发渲染(Concurrent Rendering) :允许渲染过程被中断、暂停、恢复甚至放弃,优先处理高优先级任务(如用户输入)。
- 优先级驱动:通过细粒度的优先级体系,动态调整任务执行顺序。
- 向后兼容:在保留 React 16 核心能力(如 Fiber 架构)的基础上扩展新特性,确保现有应用平滑迁移。
二、核心层实现细节
1. 调度器(Scheduler):任务优先级与执行控制
调度器是并发渲染的 “大脑”,负责决定何时执行哪个任务,核心实现包括:
-
优先级体系:定义了 5 级优先级(从高到低):
Immediate:同步执行,最高优先级(如用户输入事件)。UserBlocking:用户阻塞级(如点击、滚动等交互),需在 25ms 内完成。Normal:普通优先级(如网络请求后的 UI 更新)。Low:低优先级(如非紧急的数据处理)。Idle:空闲时执行(如日志上报)。
-
时间切片(Time Slicing) :基于
MessageChannel实现(替代 React 16 的requestIdleCallback),将长任务拆分为多个小任务,每个任务执行不超过 5ms,避免阻塞主线程。 -
任务中断与恢复:维护任务队列,高优先级任务可中断低优先级任务,低优先级任务在后续空闲时从断点恢复执行。
2. 协调器(Reconciler):Fiber 架构与并发 Diff
协调器负责对比新旧虚拟 DOM(Fiber 树),生成更新计划,核心实现:
-
Fiber 数据结构:每个 Fiber 节点对应一个组件,包含:
{ type: 组件类型(如 div、FunctionComponent), props: 组件属性, stateNode: 真实 DOM 节点(或组件实例), child: 子 Fiber 节点, sibling: 兄弟 Fiber 节点, return: 父 Fiber 节点, effectTag: 更新标记(如插入、删除、更新) ...... } -
并发 Diff 算法:
- 与 React 16 的同步 Diff 不同,React 18 的 Diff 过程可被中断:遍历 Fiber 树时,每处理一个节点就检查是否有高优先级任务,若有则暂停当前 Diff,保存进度后让出主线程。
- 恢复时从上次中断的 Fiber 节点继续处理,避免重复计算。
-
优先级排序:协调器会根据任务优先级优先处理高优先级 Fiber 节点(如用户输入触发的组件更新),低优先级节点可延迟处理。
3. 渲染器(Renderer):并发提交与批处理优化
渲染器负责将协调器生成的更新计划应用到实际平台(如 DOM),核心实现:
-
并发提交(Concurrent Commit) :
- 提交阶段是 “原子操作”(不可中断),但 React 18 支持 “选择性提交”:仅提交高优先级更新,低优先级更新暂存,避免因混合优先级更新导致的 UI 闪烁。
- 通过 “双缓存机制” 维护当前屏幕上的 Fiber 树(current)和正在构建的 Fiber 树(workInProgress),提交时只需切换指针即可。
-
自动批处理(Automatic Batching) :
- React 16 仅在 React 事件回调中支持批处理(合并多次
setState)。 - React 18 扩展到全场景:
setTimeout、Promise.then、异步函数等场景下的多次状态更新会自动合并,减少 DOM 操作次数。
- React 16 仅在 React 事件回调中支持批处理(合并多次
-
多根渲染(Multiple Roots) :通过
ReactDOM.createRoot支持同一页面渲染多个独立根节点,共享调度和协调逻辑,适合大型应用的模块化拆分。
三、应用层:并发特性 API
React 18 新增了一批 API 让开发者直接控制并发渲染,核心包括:
-
ReactDOM.createRoot:替代ReactDOM.render,是开启并发模式的入口:// React 16 ReactDOM.render(<App />, document.getElementById('root')); // React 18 const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />); -
useTransition:将非紧急更新标记为 “过渡更新”(低优先级),避免阻塞用户交互:const [isPending, startTransition] = useTransition(); // 高优先级:输入框更新 setInputValue(input); // 低优先级:过滤列表(被标记为过渡更新) startTransition(() => { setFilteredList(filterList(input)); }); -
useDeferredValue:为状态生成延迟版本,自动适配并发渲染的中间态:// 原始状态(高优先级) const [query, setQuery] = useState(''); // 延迟状态(低优先级,自动跟随 query 更新) const deferredQuery = useDeferredValue(query); // 用延迟状态渲染非紧急 UI(如长列表) return <List items={filterItems(deferredQuery)} />;
四、关键流程:从更新触发到渲染完成
以用户输入触发更新为例,React 18 的核心流程如下:
- 触发更新:用户输入(如点击按钮)调用
setState或useState的更新函数。 - 创建更新对象:创建Update对象和优先级,把更新对象加入到当前fiber节点的更新队列中(updateQueue内部是个链表结构)。
- 冒泡到根节点:markUpdateLaneFromFiberToRoot调用,从当前fiber把本次更新的优先级冒泡到根节点。
- 调度任务:调度器根据更新来源(如用户交互)分配高优先级,将任务加入队列。
- 并发协调:协调器启动 Fiber Diff,遍历组件树生成更新计划,过程中若有更高优先级任务则中断并让出主线程。
- 提交更新:协调完成后,渲染器将高优先级更新批量提交到 DOM,低优先级更新暂存。
- 清理与恢复:高优先级任务完成后,调度器恢复低优先级任务的协调与提交。
上图是我从社区看到的,把react整体的运行流程基本上画的很清晰,这边就是为了看的明白些,就不自己在重新画了。
五、总结
React 18 的架构设计围绕 “并发渲染” 展开,通过:
- 调度器实现任务优先级与中断控制;
- 协调器基于 Fiber 架构支持并发 Diff;
- 渲染器优化提交逻辑与批处理;
- 应用层 API 让开发者掌控渲染优先级。
这一架构使 React 应用在处理复杂场景(如大数据渲染、高频交互)时,既能保证用户体验流畅,又能兼顾开发效率,是 React 从 “同步渲染” 到 “可控并发渲染” 的里程碑升级。