Fiber 架构工作原理
一句话总结: Fiber 就是把原来一次性同步阻塞的渲染,改成可中断、可恢复、可调度的异步任务,让浏览器不卡顿。
1. 为什么要有 Fiber?#
React 16 之前叫 Stack Reconciler(栈协调器)
- 虚拟 DOM diff 是同步递归执行的
- 一旦开始,就必须执行完,中途不能停
- 计算量大时,JS 会阻塞浏览器渲染、交互(掉帧、卡顿)
Fiber 要解决的核心问题: 让 React 的更新任务可以被打断、优先保证高优任务(点击、输入),再回头继续渲染。
2. Fiber 核心概念#
① Fiber Node#
每个 React 元素,都会对应一个 Fiber 节点,它是一个普通 JS 对象,包含:
type:组件类型props:属性child / sibling / return:构成链表树alternate:新旧 Fiber 树的连接(双缓冲)effectTag:标记要做什么操作(新增、删除、更新)priority:任务优先级
② Fiber 树 = 链表结构#
不再是递归树,而是单链表:
child:第一个子节点sibling:兄弟节点return:父节点
这样遍历不需要递归栈,可以随时暂停/继续。
3. Fiber 两大阶段(最关键)#
Fiber 把整个更新流程切成两阶段:
阶段一:Reconciliation / Render 阶段(可中断)#
做 diff,生成 Fiber 树,标记副作用
- 遍历 Fiber 树
- 对比新旧节点
- 标记每个节点:增/删/改
- 此阶段可以被高优任务打断
- 可能执行多次,不操作真实 DOM
阶段二:Commit 阶段(不可中断)#
一次性把所有修改同步到真实 DOM
- 执行所有 effectTag
- 操作 DOM
- 执行生命周期 / useEffect
- 一旦开始必须执行完,保证 DOM 一致性
4. 调度机制:Scheduler(调度器)#
Fiber 配合调度器实现:
- 给任务分优先级
- Immediate(最高,同步)
- UserBlocking(点击、输入)
- Normal(普通更新)
- Low
- Idle(最低)
- 利用 requestIdleCallback / MessageChannel 模拟时间切片
- 每执行一小段任务,就让出主线程给浏览器
- 有空再回来继续执行
一句话: 把一大坨计算,切成一小片一小片,浏览器有空就做,没空就先响应用户。
5. 工作流程(极简版)#
- 触发更新(setState、props 变化)
- Scheduler 分配优先级
- 进入 Render 阶段:
- 从根节点开始遍历 Fiber 链表
- diff 标记更新
- 时间片用完 → 暂停
- 高优任务来了 → 打断,先处理高优
- Render 完成,得到副作用列表
- 进入 Commit 阶段:
- 一次性更新 DOM
- 执行 useEffect、useLayoutEffect
6. 与老架构 Stack 的区别#
| 特性 | Stack 架构 | Fiber 架构 |
|---|---|---|
| 执行方式 | 同步递归 | 异步可中断 |
| 能否暂停 | 不能 | 能 |
| 能否恢复 | 不能 | 能 |
| 优先级 | 无 | 支持优先级调度 |
| 主线程阻塞 | 严重 | 极小 |
| 遍历结构 | 树递归 | 链表循环 |
7. 一句话记住 Fiber#
Fiber = 链表结构 + 可中断 Render + 优先级调度 + 不可中断 Commit 让 React 从“卡死式同步渲染”变成“流畅异步协作式渲染”。