fiber框架的工作原理
面试速答(30 秒版 TL;DR)
- 以下内容以 React 18/19 的 Fiber 架构为背景。
- Fiber 本质上不是一个“新 API”,而是 React 内部的一套 数据结构 + 调度执行模型。
- 它把一次整树更新拆成很多可管理的工作单元,让 React 能做三件事:暂停、恢复、插队。
- React 更新仍然分两大阶段:
render阶段:构建新的 Fiber 树、计算差异、收集副作用,可以被打断。commit阶段:真正提交 DOM、ref、effect,必须一次完成。
- 一句话总结:Fiber 让 React 从“同步递归刷完整棵树”,升级成“按优先级调度的一组可拆分任务”。
一、先建立心智模型:Fiber 是“工作单元节点”
以前很多人把 Fiber 简单理解成“新的 diff 算法”,这个说法太窄。
更准确地说,Fiber 节点代表的是:
- 一个组件实例对应的内部节点
- 一段待完成的工作
- 一组与本次更新相关的状态和副作用信息
一个 Fiber 节点里通常会挂这些核心信息:
- 组件类型、
key pendingProps、memoizedPropsmemoizedStatereturn、child、siblingflagslanesalternate
你可以把它理解成:
- VNode 更像结果描述
- Fiber 更像 React 在运行时真正操作的工作节点
二、为什么 Fiber 树通常有两棵
React 更新时,通常同时维护两套视图树:
current:当前屏幕上已经提交的 Fiber 树workInProgress:这次更新正在计算的新 Fiber 树
这就是常说的“双缓存树”。
它的好处是:
- 当前界面继续稳定显示。
- React 可以在后台慢慢算新树。
- 算完后再一次性交换指针,把新树切成
current。
所以 Fiber 的关键不只是“树”,而是 允许一边保留当前结果,一边准备下一版结果。
三、一次更新在 Fiber 里怎么流动
1. 触发更新
更新来源可能是:
setStatedispatch- 父组件重新渲染
- Context 变化
- Suspense 重试
React 收到更新后,会先给这次更新分配优先级,并把更新挂到对应 Fiber 的更新队列上。
2. 进入 render 阶段
这一步主要做“计算”,不是立刻操作真实 DOM。
React 会沿着 Fiber 树执行工作循环,常见可以拆成两步理解:
beginWork
主要做:
- 读取这次更新需要处理的数据
- 计算当前组件的新子节点
- 决定子节点是否复用
- 生成或复用子 Fiber
completeWork
主要做:
- 向上冒泡子树的副作用标记
- 为宿主节点准备 DOM 变更信息
- 把整棵子树的结果往父节点汇总
所以 render 阶段的本质是:
- 生成新的工作树
- 算清楚哪些节点要插入、更新、删除
- 不急着真正提交
3. render 阶段为什么可以被打断
因为 Fiber 把每个节点都变成了“可独立推进的一小段工作”。
React 不必像旧架构那样一旦进入递归就跑到底,而是可以在合适时机:
- 暂停当前工作
- 把控制权还给浏览器
- 先处理更高优先级任务
- 之后再继续未完成的 Fiber 工作
注意:这不是多线程,而是 同一主线程上的任务切片与调度。
4. 进入 commit 阶段
当 workInProgress 整棵树准备好后,React 才会进入 commit。
这一步通常包含三类事:
- 提交 DOM 变更
- 处理 ref
- 执行 layout effect / passive effect 相关流程
这一步不能被打断,因为如果中途停下来,界面就会落在半更新状态,产生不一致。
四、Fiber 为什么能支持优先级
面试里可以把这点答成 Fiber 的核心价值之一。
React 不会把所有更新都一视同仁。比如:
- 输入框字符回显要快
- 动画更新要尽量流畅
- 大列表筛选结果刷新可以稍后一点
Fiber 架构下,React 可以把更新拆开并配合优先级模型调度。
在现代 React 里,优先级最终体现为一组 lane。
你不用背内部常量,但要知道它解决的是:
- 哪些更新要先做
- 哪些更新可以延后
- 哪些更新可以被同批合并
五、Fiber 和 Reconciler、Renderer 的关系
这是很常见的追问。
- Reconciler 负责“怎么比较、怎么调度、怎么生成副作用”
- Renderer 负责“最终怎么落到具体平台”
比如:
- React DOM 最终改浏览器 DOM
- React Native 最终改原生视图
Fiber 属于 Reconciler 的核心内部实现。也就是说:
- Fiber 主要解决的是 协调和调度
- 不是直接操作 DOM 的那层
六、面试里最稳的回答方式
标准答法
Fiber 是 React 16 之后引入的核心架构。它把每个组件节点抽象成一个 Fiber 工作单元,并把更新从一次不可中断的同步递归,改造成可以按优先级拆分、暂停、恢复的任务系统。React 会先在 render 阶段构建 workInProgress 树并收集副作用,这一步可以被打断;等整棵树准备好后,再在 commit 阶段一次性提交 DOM 和 effect。React 18/19 的并发渲染、transition、Suspense 这些能力,底层都建立在 Fiber 之上。
七、常见追问
1. Fiber 和虚拟 DOM 是一个东西吗?
不是。
- 虚拟 DOM 更偏“UI 描述结果”
- Fiber 更偏“React 运行时工作节点”
很多 Fiber 节点最终会对应某个 VNode/Element,但二者职责不同。
2. Fiber 是不是让 React 一定更快?
不能这么答。
Fiber 的核心收益不是“所有场景绝对更快”,而是:
- 更可控
- 更可调度
- 更适合复杂交互
也就是 更稳地处理大应用更新。
3. render 可以中断,commit 为什么不能中断?
因为 render 只是算结果,中断了最多继续算;commit 是真正改界面,中途停住会让 UI 落在不一致状态。
八、易错点 / 坑
- 把 Fiber 说成“更快的 diff”。
- 把并发渲染说成“浏览器多线程并行渲染 React”。
- 只会背
render和commit,但说不出为什么要分两阶段。 - 把 Fiber 和 React DOM 混成一层,以为 Fiber 直接操作浏览器 DOM。
速记要点(可背诵)
- Fiber = 数据结构 + 调度模型。
- 每个 Fiber 节点都是一个工作单元。
render可中断,commit不可中断。- React 18/19 的并发能力建立在 Fiber 之上。