Fiber是什么
# 一、为什么 React 一定要有 Fiber?(动机)
# 1️⃣ 老 React(Stack Reconciler)的问题
在 React 16 之前,React 的更新流程是:
setState
→ 同步递归 diff
→ 一口气算完整棵树
→ 更新 DOM
1
2
3
4
2
3
4
# ❌ 问题本质
- 不可中断
- 不可暂停
- 不可恢复
如果组件树很大:
- diff 占用 JS 主线程
- 用户滚动 / 输入会卡顿
- 浏览器无法插手
👉 这和 Vue effect 模型完全不同 Vue 是“点更新”,React 是“树更新”,React 必须解决这个问题。
# 2️⃣ React 的选择
React 没走 Vue 的「更细粒度响应式」,而是选择:
- 让“render 本身”可被中断、拆分、重试
👉 Fiber 就是为这个目标设计的。
# 二、Fiber 是什么(一句话版)
- Fiber 是一种“可中断的虚拟调用栈 + 数据结构”
更直白一点:
- Fiber = 把递归 diff,改写成「可暂停的循环任务」
# 三、Fiber 的本质:把“树”变成“链表 + 栈”
# 1️⃣ 一个 Fiber 节点是什么?
每个 Fiber 节点 = 一个组件 / DOM 节点
interface Fiber {
type // 组件类型
key
stateNode // DOM 或 class 实例
return // 父 fiber
child // 第一个子 fiber
sibling // 下一个兄弟 fiber
pendingProps
memoizedProps
memoizedState // hooks 就在这
flags // 副作用标记
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
⚠️ 注意: Fiber 不是 Virtual DOM Virtual DOM 是 描述 UI Fiber 是 调度 + 执行单元
# 2️⃣ 为什么是 child / sibling / return?
因为这样可以:
- 不用递归
- 用 while 循环
- 每一步都可以暂停
App
└─ A
├─ B
└─ C
1
2
3
4
2
3
4
变成:
App.child → A
A.child → B
B.sibling → C
1
2
3
2
3
# 四、Fiber 的核心能力:可中断 render
# 1️⃣ render 阶段(可中断)
React 把更新分成两步:
Render 阶段(可中断)
Commit 阶段(不可中断)
1
2
2
# Render 阶段做什么?
- 执行组件函数
- 调用 Hooks
- diff Fiber
- 标记 flags(增 / 删 / 改)
👉 不操作 DOM
# 2️⃣ Commit 阶段(必须一次完成)
- 操作 DOM
- 执行 useEffect cleanup / create
- ref 赋值
👉 一旦进入,绝不中断
# 3️⃣ 中断是怎么实现的?
while (nextUnitOfWork && !shouldYield()) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork)
}
1
2
3
2
3
shouldYield():浏览器要控制权- 保存当前 Fiber
- 下次从这里继续
👉 Fiber = 可恢复的执行上下文
# 五、Fiber 和 Scheduler 的关系(并发来源)
# 1️⃣ Scheduler 决定“什么时候跑”
- requestIdleCallback(早期)
- MessageChannel
- 优先级(lane)
高优先级(点击)
低优先级(列表)
1
2
2
# 2️⃣ Fiber 决定“跑到哪里停”
- 每个 Fiber = 一个 work unit
- 可暂停
- 可丢弃
- 可重做
👉 并发 = Scheduler + Fiber
# 六、为什么 Fiber 能“重跑 render”而不怕?
这是 React 的核心设计前提:
- render 必须是纯函数
同样的 props + state
→ 同样的 UI
1
2
2
所以:
- render 跑一半被丢弃 ❌ 没关系
- 再跑一遍 ✅ 一样的结果
👉 这点 Vue effect 很难做到
# 七、Fiber vs Vue effect(你最关心的对比)
| 维度 | Vue3 effect | React Fiber |
|---|---|---|
| 粒度 | 属性级 | 组件级 |
| 更新方式 | 精确触发 | render 重跑 |
| 中断能力 | ❌ | ✅ |
| 调度友好 | 一般 | 极强 |
| 并发基础 | scheduler + job | scheduler + fiber |
一句话总结:
- Vue 用「更细的依赖」避免算
- React 用「可中断计算」硬算
# 八、Hooks 为什么必须依赖 Fiber?
因为:
- Hooks 状态存在
fiber.memoizedState - render 重跑时按顺序取
- Fiber 保证 同一组件的 Hook 链稳定
Fiber
└─ memoizedState
├─ hook1
├─ hook2
└─ hook3
1
2
3
4
5
2
3
4
5
👉 没有 Fiber,就没有 Hooks
# 九、常见误解澄清(面试高频)
# ❌ Fiber = 并发
- Fiber 是基础设施,不等于并发
# ❌ Fiber = 更快
- Fiber 有时更慢,但更“可控”
# ✅ Fiber = 可调度、可中断、可恢复
# 十、终极一句话总结
- Fiber 不是为了性能,而是为了“让 React 能被操作系统一样调度”
上次更新: 2026/01/09, 03:15:08