React Fiber

本文最后更新于 2025年8月25日 晚上

参考:https://juejin.cn/post/6844903975112671239

概括

Fiber 架构是 React 16 及以后的版本采用的全新的协调引擎机制,主要解决了 React 在渲染过程当中存在的一些性能问题,尤其是主线程被长时间占用导致的页面卡顿、掉帧、响应延迟等问题,并且为并发渲染等高级特性奠定了基础。

React Fiber 本质上是为了解决 React 更新效率低的问题,没有降低整体的工作量,该做的还是要做。不要期望 Fiber 能给现有应用带来质的提升,如果性能问题是开发者造成的,自己的锅还是得自己背。因此 React 也在考虑利用 CPU 空闲或者 I/O 空闲期间做一些预渲染。

为什么需要 Fiber

在 React 16 之前,React 使用的是 Stack Reconciler(栈协调器)。它的工作方式是递归、同步的:

  • 同步且不可中断:当 React 开始更新时,它会递归地调用每个组件的 render 方法,生成新的虚拟 DOM 树(Virtual DOM),并与旧的树进行对比(Diffing),然后找出需要更新的部分。这个过程是一气呵成的,会一直占用主线程
  • 所以如果组件层级非常深或者 Diff 计算量很大,这个同步过程可能会超过 16ms(一帧的时间)。浏览器无法中断这个过程去处理更高优先级的任务(如用户输入、动画等),从而导致渲染过程的阻塞导致页面响应缓慢,用户体验变差

Fiber 架构通过任务分片优先级调度,提高了渲染的流畅度和交互体验,解决了这个问题。

Fiber 是什么

Fiber 架构的核心思想是将原本同步不可中断的递归 diff + patch 协调过程,改为异步可中断、可分段执行的更新过程。为了实现这个目标,Fiber 从两个层面进行了重新设计:

  • Fiber 是一种数据结构
    • 可以把它理解为 “虚拟栈帧” 或 “工作单元”
    • React 会将虚拟 DOM 节点映射到 Fiber 节点上。每个 Fiber 节点都保存了组件类型、对应 DOM 节点、每次更新的 props、state 等数据以及与其他 Fiber 节点的链接关系(链表结构)
    • 这些链接关系包括:child(第一个子节点)、sibling(下一个兄弟节点)、return(父节点),这使得 React 不再依赖递归调用栈,而是可以通过链表来线性遍历整个组件树
  • Fiber 是一种工作单元机制
    • React 将渲染更新过程分解成一个个小的工作单元,每个工作单元就是处理一个 Fiber 节点
    • React 有一个 “调度器(Scheduler)”,它会基于浏览器的 requestIdleCallbackrequestAnimationFrame 等 API 来在浏览器的空闲时段分片执行这些工作单元
    • 可中断与恢复:如果在处理某个 Fiber 节点时当前帧的空闲时间用完,React 可以暂停当前的工作,把控制权交还给浏览器,让浏览器去处理更高优先级的任务(比如用户点击等)。等到下一帧再有空闲时间时 React 再从上次中断的地方继续执行
    • 优先级调度:不同类型的更新(如用户输入、动画、数据加载)可以被赋予不同的优先级。高优先级的更新可以“插队”,中断正在进行的低优先级更新

Fiber 工作流程

Fiber 架构下的工作流程:

  • Reconciliation(协调阶段)/Render(渲染阶段)
    • 内容:diff 算法对比新的虚拟 DOM 和旧的虚拟 DOM,确定需要更新的节点。可中断
    • 过程:React 会在 Fiber 树上遍历并更新,为每个 Fiber 节点执行对应的其生命周期方法(如 getDerivedStateFromPropsshouldComponentUpdate),调用 render 方法生成子节点并进行 diff 比较,最终标记出需要执行的 DOM 更新
    • 这个阶段在内存中进行,即使被中断、重复执行,也不会更新实际 UI,用户看不到半成品,而且过程是被分割成若干个小的任务,React 会在每个小任务之间做调度,如在任务中断时去执行其他高优先级的任务,等有机会再继续执行,确保用户交互体验更好
  • Commit(提交阶段)
    • 内容:将上一阶段计算出的所有更新,一次性、同步地应用到真实的 DOM 上。不可中断
    • 过程:React 会执行生命周期方法(如 getSnapshotBeforeUpdatecomponentDidMountcomponentDidUpdate)并更新 DOM
    • 为了保证 UI 的一致性,这个过程必须快速完成,所以是同步且不可中断的

渲染时以 fiber 节点为单位,并通过任务分片优先级调度来优化过程。任务分片和优先级调度机制:

  • 任务分片:React 把渲染任务分割成多个小的 fiber 节点,每个节点对应虚拟 DOM 中的一部分,这些节点将通过优先级调度逐步执行
  • 优先级调度:React 给每个任务分配一个优先级,例如:
    • 高优先级任务:如用户输入、动画等,React 会优先执行
    • 低优先级任务:如低优先级的渲染工作,可以等到空闲时再执行
  • 任务中断:如果某个任务正在执行时用户发生了新交互(如点击、输入等),React 会中断当前的低优先级任务,优先处理高优先级的任务。中断的任务会保留状态,等到有空余时间时继续执行

优势好处

在 React 15 中更新是同步的,React 会一次性计算完所有的虚拟 DOM 然后更新页面。在 React 16 中引入了 Fiber 架构,更新过程被分成了多个小任务,可以根据任务优先级进行中断、恢复,并且实现了异步渲染:

  • 异步渲染:Fiber 架构的最大特点是异步渲染。通过任务分片和优先级调度,React 可以在渲染的过程中暂停、恢复,防止长时间的 UI 阻塞
  • 交互体验:用户交互(比如点击、输入等)会触发高优先级任务,React 会中断当前的渲染过程,快速响应用户输入,使应用更加流畅
  • 提高性能:借助 Fiber 的优先级调度,React 可以根据不同任务的优先级来决定执行顺序,提高了应用的响应速度和流畅度,进一步优化性能

React Fiber
https://xuekeven.github.io/2025/08/24/React Fiber/
作者
Keven
发布于
2025年8月24日
更新于
2025年8月25日
许可协议