深入理解 React Fiber:重新定义的渲染引擎
KongHou

React 16 是一次历史性的重构,它不只是版本升级,更是底层架构的“换心手术”。
它让 React 从同步的 Stack Reconciler 进入了可中断、可恢复、可调度的 Fiber 架构时代。


一、为什么要有 Fiber?

在 React 15 及之前的版本中,React 使用的是 Stack Reconciler(栈调和算法)
它的最大问题是:渲染过程是同步、不可中断的。

当组件树很大、或更新量很高时(例如动画、大量数据渲染),一次渲染可能会持续几十毫秒甚至更久。
这会造成浏览器主线程被长时间占用,导致:

  • 页面掉帧、卡顿;
  • 用户交互延迟;
  • 动画不流畅。

例如,当用户在输入框打字时,如果 React 正在重绘一棵庞大的组件树,那么输入响应会出现明显延迟。
因此 React 团队决定从底层重写调和器,这就是 Fiber Reconciler 的诞生。


二、React Fiber 的出现

🧩 Fiber Reconciler

Fiber 是对 React 内部渲染机制的彻底重构,它的目标是:

  • 可中断(interruptible);
  • 可恢复(resumable);
  • 可分片执行(incremental);
  • 支持任务优先级调度(prioritized scheduling)。

这套机制让 React 在执行复杂渲染时仍能保持流畅的用户体验。


三、什么是 Fiber?

Fiber 是 React 组件的“虚拟执行单元”
可以理解为:React 把组件渲染的工作切分成一个个“小任务”,每个小任务就是一个 Fiber。

每个 Fiber 实际上是一个对象,保存了组件节点在不同阶段所需的各种信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
const fiber = {
type, // 组件类型(函数组件、类组件、DOM 节点等)
key, // diff 用的 key
stateNode, // 对应的真实 DOM 或组件实例
child, // 子 Fiber
sibling, // 兄弟 Fiber
return, // 父 Fiber
pendingProps, // 新的 props
memoizedProps, // 上一次的 props
memoizedState, // 上一次的 state
alternate, // 旧 Fiber(用于 diff)
flags, // 变更标记(插入、更新、删除等)
};

Fiber 节点通过 childsiblingreturn 三个指针形成单向链表结构。
相比传统递归调用栈结构,Fiber 链表更灵活,可暂停、恢复或重做。


四、Fiber 的运行阶段

React Fiber 的工作过程分为两个阶段:

1️⃣ Render(协调)阶段

  • 又称 Reconciliation 阶段
  • React 会构建新的 Fiber 树;
  • 比较新旧 Fiber(diff);
  • 标记需要更新的节点;
  • 这一步 可中断、可恢复、可分片执行

React 会利用浏览器空闲时间(requestIdleCallbackscheduler)逐步执行任务。


2️⃣ Commit(提交)阶段

  • 把 Render 阶段标记的变更一次性提交到真实 DOM;

  • 同步执行、不可中断

  • 分为三个子阶段:

    • Before mutation(变更前)
    • Mutation(执行 DOM 变更)
    • Layout(触发回调)

简而言之:
Render 阶段在“思考怎么改”;
Commit 阶段在“真正去改”。


五、时间切片(Time Slicing)与可中断更新

React Fiber 引入了 时间切片(Time Slicing) 概念。

可以理解为:

React 不再一口气干完所有任务,而是把渲染任务拆分成许多小片段,在空闲时间逐步完成。

执行过程伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
function workLoop(deadline) {
while (nextFiber && deadline.timeRemaining() > 0) {
nextFiber = performUnitOfWork(nextFiber);
}

if (nextFiber) {
requestIdleCallback(workLoop); // 时间不够,暂停
} else {
commitRoot(); // 协调完成,进入提交阶段
}
}

每完成一个 Fiber 单元,React 都会判断:

1
shouldYield(); // 是否让出主线程?

如果浏览器有更高优先级的任务(如用户输入、滚动、动画),React 就会暂停渲染,下次空闲时继续。
这使得 React 的 UI 更新更加流畅,不会“卡死”主线程。


六、优先级调度机制(Scheduler)

React Fiber 引入了 优先级调度系统(Scheduler),让不同任务可以按紧急程度执行。

优先级 示例任务 是否可中断
Immediate 同步任务(事件回调)
User-blocking 用户输入
Normal 普通状态更新
Low 后台数据预加载
Idle 非关键后台任务

React 会根据任务优先级动态调度,保证关键交互(如输入、动画)优先渲染。


七、Fiber 树的“双缓存机制”

React 内部同时维护两棵 Fiber 树:

树名称 含义
current 当前正在显示的 Fiber 树
workInProgress 正在构建的新 Fiber 树

当新树构建完毕后,React 会在 Commit 阶段workInProgress 替换掉 current
这种“双缓存机制(Double Buffering)”保证了渲染过程的一致性与原子性。


八、Fiber 与 React 18 的并发特性

React 18 在 Fiber 架构的基础上正式引入了 并发模式(Concurrent Mode),包括:

  • useTransition:低优先级状态更新;
  • useDeferredValue:延迟更新;
  • 自动批处理(Automatic Batching);
  • Suspense for Data Fetching:异步数据加载。

这些特性都基于 Fiber 的“可中断 / 可恢复”渲染机制。


九、Fiber 的核心意义

对比维度 React 15 (Stack) React 16+ (Fiber)
渲染机制 同步递归 可中断异步
数据结构 调用栈 链表 Fiber 树
调度机制 有优先级 Scheduler
可恢复性 不可恢复 可暂停 / 恢复
性能体验 大组件树易卡顿 平滑、流畅的交互

React Fiber 的价值在于:

✨ “让渲染变成一个可管理的异步过程”
React 从单线程阻塞渲染,进化为可调度、可优先级化的现代 UI 渲染引擎。


🧠 写在最后

React Fiber 不仅仅是性能优化,更是一种设计哲学:

React 不再追求“一次性渲染完”,
而是智能地“在合适的时间做合适的事”。

这是现代 UI 框架在性能与交互体验之间找到的平衡点。
Fiber 的出现,让 React 真正成为了 可感知时间的 UI 引擎


Powered by Hexo & Theme Keep
Total words 23.5k