跳到主要内容

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
  • pendingPropsmemoizedProps
  • memoizedState
  • returnchildsibling
  • flags
  • lanes
  • alternate

你可以把它理解成:

  • VNode 更像结果描述
  • Fiber 更像 React 在运行时真正操作的工作节点

二、为什么 Fiber 树通常有两棵

React 更新时,通常同时维护两套视图树:

  • current:当前屏幕上已经提交的 Fiber 树
  • workInProgress:这次更新正在计算的新 Fiber 树

这就是常说的“双缓存树”。

它的好处是:

  1. 当前界面继续稳定显示。
  2. React 可以在后台慢慢算新树。
  3. 算完后再一次性交换指针,把新树切成 current

所以 Fiber 的关键不只是“树”,而是 允许一边保留当前结果,一边准备下一版结果

三、一次更新在 Fiber 里怎么流动

1. 触发更新

更新来源可能是:

  • setState
  • dispatch
  • 父组件重新渲染
  • 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”。
  • 只会背 rendercommit,但说不出为什么要分两阶段。
  • 把 Fiber 和 React DOM 混成一层,以为 Fiber 直接操作浏览器 DOM。

速记要点(可背诵)

  • Fiber = 数据结构 + 调度模型。
  • 每个 Fiber 节点都是一个工作单元。
  • render 可中断,commit 不可中断。
  • React 18/19 的并发能力建立在 Fiber 之上。