React Fiber 架构详解
React Fiber 是 React 16 中引入的核心架构重构,其本质是一套可中断、可恢复、优先级可控的协调(Reconciliation)算法。它解决了旧架构下大型应用因同步渲染导致的页面卡顿问题,为 React 的并发特性(如 Suspense、Time Slicing)奠定了基础。
一、为什么需要 Fiber?—— 旧架构的痛点
在 React 16 之前,React 使用的是栈式协调器(Stack Reconciler),其工作流程存在根本性缺陷:
-
同步不可中断当组件树庞大时,React 会递归遍历整个虚拟 DOM 树,计算新旧节点差异(Diff)并执行 DOM 更新。这个过程是同步阻塞的,一旦开始就会占用主线程直到完成(可能持续几十甚至上百毫秒)。
-
阻塞主线程浏览器的主线程负责 JS 执行、DOM 渲染、用户交互(如点击、输入)等核心任务。若 React 同步渲染耗时过长,会导致主线程无法响应用户操作或绘制页面,表现为页面卡顿、输入延迟、动画掉帧。
-
无优先级概念所有更新(如用户输入、动画、数据请求回调)优先级相同,无法优先处理关键任务(如输入框打字),非关键任务(如列表滚动加载)可能阻塞关键任务。
二、Fiber 的核心目标
Fiber 架构的设计初衷是解决旧架构的痛点,核心目标可概括为三点:
- 中断与恢复:将同步的渲染任务拆分为小块单元(Fiber 节点),每处理完一个单元就检查是否有更高优先级任务,若有则暂停当前任务,优先处理高优先级任务,之后再恢复原任务。
- 优先级调度:为不同类型的更新分配优先级(如用户输入 > 动画 > 数据请求),确保关键任务优先执行,提升用户体验。
- 并发渲染:支持 “同时” 处理多个更新(逻辑上的并发,非多线程),例如在渲染一个列表的同时,响应用户的输入操作。
三、Fiber 的核心概念
要理解 Fiber 架构,需先掌握以下关键概念:
1. Fiber 节点:渲染任务的最小单元
Fiber 本质是一个数据结构,它既代表虚拟 DOM 节点的 “替身”,也存储了该节点的渲染相关信息(如类型、属性、优先级、依赖等)。每个 React 元素(如 div、自定义组件)都会对应一个 Fiber 节点。
Fiber 节点的核心属性(简化版)如下:
| 属性名 | 作用说明 |
|---|---|
type |
节点类型(如 div、FunctionComponent、ClassComponent) |
key |
用于 Diff 算法中识别相同节点,优化复用 |
stateNode |
关联的真实 DOM 节点(宿主组件)或组件实例(类组件) |
return |
父 Fiber 节点(指向当前节点的父级) |
child |
子 Fiber 节点(指向当前节点的第一个子级) |
sibling |
兄弟 Fiber 节点(指向当前节点的下一个兄弟,解决单链表遍历子节点问题) |
pendingProps |
待处理的 props(更新发生时,新 props 先存于此) |
memoizedProps |
已处理的 props(当前渲染使用的 props,用于 Diff 对比) |
memoizedState |
已处理的 state(类组件的 state 或函数组件的 Hooks 链表) |
tag |
节点标记(如 HostComponent 表示 DOM 元素,FunctionComponent 表示函数组件) |
priority |
节点更新的优先级(决定该任务是否被中断) |
effectTag |
副作用标记(如 Placement 表示需要插入 DOM,Update 表示需要更新 DOM) |
nextEffect |
下一个有副作用的 Fiber 节点(用于快速遍历副作用链,优化 DOM 更新) |
2. Fiber 树:双缓存机制
React 中存在两棵 Fiber 树:
- Current Fiber 树:当前页面渲染对应的 Fiber 树,与真实 DOM 结构一致。
- WorkInProgress Fiber 树:正在构建的 Fiber 树,基于当前更新计算新的节点状态和差异。
这种 “双缓存” 机制的优势在于:
- 避免 DOM 操作冲突:所有更新都在 WorkInProgress 树上计算,不直接修改 Current 树关联的真实 DOM。
- 原子性更新:当 WorkInProgress 树构建完成后,只需将 React 的
current指针指向 WorkInProgress 树,即可完成一次 “无缝” 更新,避免页面出现中间状态。
切换过程:
- 初始渲染时,构建 WorkInProgress 树,完成后将
current指向它,成为 Current 树。 - 后续更新时,基于 Current 树的节点复制生成新的 WorkInProgress 节点,计算差异后,再次切换
current指针。
3. 调度器(Scheduler):优先级管理核心
调度器是 Fiber 架构的 “大脑”,负责:
- 为不同类型的更新分配优先级。
- 管理任务队列,决定何时执行哪个任务(WorkInProgress 树的构建)。
- 控制任务的中断与恢复(通过浏览器的
requestIdleCallback或自定义定时器实现)。
优先级划分(React 内部逻辑,非暴露 API)
React 根据更新的 “紧急程度” 将优先级分为多个级别(从高到低):
- Immediate:紧急更新(如用户输入、页面报错),必须立即执行,不可中断。
- UserBlocking:用户阻塞型更新(如点击按钮后的状态变化、动画帧更新),优先级高,需尽快执行。
- Normal:普通更新(如数据请求后的列表渲染),优先级中等,可被高优先级任务中断。
- Low:低优先级更新(如非关键的日志统计、延迟加载非可见区域内容),可延迟执行。
- Idle:空闲时更新(如非紧急的 DOM 操作优化),仅在主线程完全空闲时执行。
调度逻辑
- 当有更新触发时(如
setState、useState),React 会创建一个 “更新任务”,并由调度器分配优先级。 - 调度器通过
requestIdleCallback(或自定义的requestAnimationFrame封装)向浏览器 “请求” 空闲时间。 - 浏览器空闲时,调度器执行任务:构建 WorkInProgress 树(处理一个 Fiber 节点)。
- 处理完一个 Fiber 节点后,检查是否有更高优先级任务,或浏览器是否需要抢占主线程(如处理用户输入):
- 若有,则暂停当前任务,将其放回任务队列。
- 若无,则继续处理下一个 Fiber 节点。
4. 协调(Reconciliation)与提交(Commit)
Fiber 架构的工作流程分为两个核心阶段,这两个阶段的分离是 “可中断” 特性的关键:
阶段 1:协调阶段(Reconciliation Phase)—— 可中断
也称为 “渲染阶段”,核心任务是计算差异:
- 从根 Fiber 节点开始,遍历(深度优先)所有 Fiber 节点,生成对应的 WorkInProgress Fiber 节点。
- 对每个节点进行 Diff 对比(对比
type、key、props等),确定该节点是否需要更新、删除或新增。 - 为需要操作的节点标记
effectTag(如Placement、Update、Deletion),并构建 “副作用链”(nextEffect链表),方便后续批量处理。 - 若过程中出现更高优先级任务,或浏览器需要主线程,当前协调任务会被中断,待空闲时从上次中断的 Fiber 节点继续恢复。
关键特点:此阶段不操作真实 DOM,仅在内存中计算差异,因此中断不会影响用户体验。
阶段 2:提交阶段(Commit Phase)—— 不可中断
核心任务是执行 DOM 操作,此阶段必须一次性完成,不可中断(否则会导致 DOM 状态不一致):
- Before Mutations:执行
getSnapshotBeforeUpdate(类组件生命周期)等钩子,获取更新前的 DOM 快照。 - Mutations:遍历 “副作用链”,根据
effectTag执行对应的 DOM 操作(插入、更新、删除 DOM 节点)。 - Layout:更新
current指针,将 WorkInProgress 树切换为 Current 树;执行componentDidMount、componentDidUpdate等生命周期钩子,或useEffect的回调函数;更新 Refs。
关键特点:此阶段直接操作真实 DOM,若中断会导致页面出现 “半成品” DOM,因此必须同步执行。
四、Fiber 架构的优势总结
- 解决页面卡顿:通过任务拆分和中断恢复,避免长时间占用主线程,确保用户交互(如输入、点击)和动画的流畅性。
- 支持优先级调度:关键任务(如用户输入)优先执行,非关键任务延迟执行,提升用户体验。
- 奠定并发基础:为 React 后续的并发特性(如
Suspense异步加载、useDeferredValue延迟更新)提供了底层支持。 - 内存高效:双缓存机制避免了重复创建节点,副作用链优化了 DOM 操作的批量执行。
五、常见疑问:Fiber 与 Virtual DOM 的关系?
Fiber 并非替代 Virtual DOM,而是对 Virtual DOM 协调过程的底层重构:
- Virtual DOM:是 React 对真实 DOM 的抽象表示,本质是描述 UI 结构的 JS 对象,核心作用是 “减少 DOM 操作”。
- Fiber:是 Virtual DOM 的 “增强版载体”,它不仅包含了 Virtual DOM 的信息(
type、props),还增加了调度、优先级、中断恢复所需的元数据(priority、effectTag、return/child/sibling指针)。
简单来说:Virtual DOM 定义了 “要渲染什么”,而 Fiber 定义了 “如何高效地计算和渲染”。
六、总结
React Fiber 架构的核心是通过数据结构重构(Fiber 节点)、任务拆分(可中断)、优先级调度(Scheduler)、双缓存树(Current/WorkInProgress) 这四大支柱,解决了旧架构的同步阻塞问题。它不仅提升了大型 React 应用的性能,更重要的是为 React 的并发特性提供了底层支撑,是 React 从 “同步渲染” 迈向 “并发渲染” 的关键一步。
理解 Fiber 架构,能帮助开发者更深入地理解 React 的更新机制(如为什么 useEffect 在 DOM 更新后执行、Suspense 如何实现异步加载),从而写出更高效的 React 代码。
更多推荐
所有评论(0)