Skip to content
目录

Fiber 架构详解

1. Fiber 是什么

Fiber 是 React 16 引入的新架构,是对 React 核心算法的重写。Fiber 既是一种数据结构,也是一种架构模式。

1.1 Fiber 作为数据结构

Fiber 是一个 JavaScript 对象,表示一个工作单元,包含组件的类型、状态、副作用等信息。

1.2 Fiber 作为架构

Fiber 架构使得 React 能够:

  • 可中断渲染:将渲染工作分成多个小任务,可以暂停和恢复
  • 优先级调度:根据优先级决定先执行哪些任务
  • 增量更新:可以逐步更新 UI,而不是一次性完成

工作流程

1.调和阶段 1.1 React 会将整个渲染任务拆分成多个小的工作单元(Fiber 节点) 1.2 拆分成 beginWork 和 completeWork 1.2.1 beginwork:挂载更新 各个 hooks(hooks允许在不编写 class 的情况下使用 state 以及 React 的其他特性 包含 state、effect) ,存到memoizedState 1.3 构建新的 Fiber 树(workInProgress)

2. Fiber 树结构

Fiber 节点通过以下字段形成树结构:

Fiber
├── child      → 第一个子节点
├── sibling    → 下一个兄弟节点
└── return     → 父节点

遍历顺序(深度优先):

  1. 访问当前节点
  2. 访问子节点(child)
  3. 访问兄弟节点(sibling)
  4. 回到父节点(return)

3. 双缓冲机制

React 使用双缓冲技术来优化性能:

3.1 Current Tree 和 WorkInProgress Tree

  • Current Tree:当前显示在屏幕上的 Fiber 树
  • WorkInProgress Tree:正在构建的新 Fiber 树

3.2 alternate 字段

每个 Fiber 节点都有一个 alternate 字段,指向另一个树中对应的节点:

javascript
// current.alternate === workInProgress
// workInProgress.alternate === current

3.3 工作原理

  1. 开始更新时,从 current 树克隆节点创建 workInProgress 树
  2. 在 workInProgress 树上进行更新
  3. 更新完成后,workInProgress 树成为新的 current 树
  4. 下次更新时,复用之前的节点,减少内存分配

4. 优先级系统(Lanes)

React 使用 Lanes(车道)系统管理优先级:

任务看成我一辆辆汽车,他们需要在不同的车道上行驶才不会相互影响,但是右边的车道可以向左边超车(优先级高)。这就是为什么我们称之为 车道模型。

4.1 优先级档位(5 档,从高到低)

Lane 在 ReactFiberLane.js 里用 31 位掩码表示;getHighestPriorityLane() 在待处理集合里取最靠右的 bit,对应最紧急的更新。日常所说的「优先级」通常指下面 5 个主档位(与 lanesToEventPriority → Scheduler 五档的映射一致,详见 05-Scheduler调度器):

  1. SyncLane — 离散交互、flushSync 等,需尽快同步完成
  2. InputContinuousLane — 连续输入(滚动、拖拽、mousemove 等),可分批处理但不能长期饿死
  3. DefaultLane — 未单独分级的普通更新(多数 setState、请求返回后的渲染)
  4. TransitionLanesstartTransition / useDeferredValue(占 14 个 bit,可并存多个 transition)
  5. IdleLanes — 可无限推迟的后台工作

Hydration 还有与上表同档的 *HydrationLane 变体,专用于 SSR 注水。

不算在上述五档里的辅助车道(不要和「5 个优先级」混为一谈):

  • RetryLanes(4 bit):Suspense 在 Promise 就绪后的重试
  • OffscreenLane:离屏 / 预渲染内容

原先只列 Sync、Transition、Retry、Idle,漏了 InputContinuous 与 Default 两档,且把 Retry 当成了与 Transition 并列的主层级。

5. 副作用标记(Flags)

React 使用 Flags 标记副作用:

5.1 副作用类型

  • Placement:需要插入 DOM
  • Update:需要更新 DOM
  • Deletion:需要删除 DOM
  • Passive:useEffect 副作用
  • Layout:useLayoutEffect 副作用

6. Fiber 架构的优势

6.1 可中断渲染

  • 可以将渲染工作分成多个小任务
  • 可以在任务之间让出控制权
  • 可以暂停低优先级任务,优先处理高优先级任务

6.2 优先级调度

  • Sync / InputContinuous:点击、键盘、滚动等用户感知路径优先
  • Default / Transition:普通状态更新 vs 可打断的过渡更新
  • Idle:后台任务最后执行

6.3 增量更新

  • 可以逐步更新 UI
  • 不会阻塞主线程
  • 提供更好的用户体验

7. Fiber 架构的设计原则

根据 Fiber Principles

  1. 在 beginWork 和 completeWork 中可以修改 Fiber
  2. 不能在这些阶段之外有全局副作用
  3. 使用固定的数据结构:Fiber 节点结构固定,不能动态添加字段
  4. 避免动态分发:减少函数调用开销

MIT License.