Skip to content

React Fiber 的概念与工作原理

React 中, 每个函数组件的实例并不直接是一个 Fiber, 但每个组件确实都有一个与之对应的 Fiber 节点. FiberReact 用来管理和调度组件渲染的内部机制. React Fiber 引入了一种全新的架构, 帮助解决了之前同步渲染带来的性能问题. 让我们详细说明 Fiber 的历史背景、数据结构及工作原理.

React Fiber 的历史背景与产生原因

React Fiber 出现之前, React 使用的是同步渲染模型, 这意味着每次更新时, React 会一次性从头到尾完成整个组件树的渲染. 如果组件树庞大或者渲染操作复杂, 这会导致 UI 卡顿, 用户体验变差.

React Fiber 产生的主要原因是为了解决以下问题:

  1. 性能问题:同步渲染无法分割渲染任务, 导致 React 的 UI 响应速度下降, 尤其是在复杂场景下.
  2. 响应性React Fiber 通过引入增量渲染, 让渲染过程可以分成小任务, 在任务之间可以让出控制权给浏览器, 处理更高优先级的任务 (如用户输入) , 从而提升应用的响应速度.

什么是 Fiber?

FiberReact 16 引入的一种基于链表的数据结构, 用来表示组件树中的每个组件. 它使 React 能够将渲染工作分解为多个小任务, 并允许在执行这些任务的过程中暂停、继续或丢弃它们. Fiber 实现了并发渲染任务优先级调度, 从而提高了渲染的灵活性和性能.

函数组件与 Fiber 的关系

React 的渲染流程中, 每个组件 (无论是函数组件还是类组件) 都会有一个对应的 Fiber 节点. Fiber 节点记录了该组件的状态、DOM 信息以及与组件渲染相关的其他元数据.

  • 函数组件本质上是一个普通的 JavaScript 函数, 没有实例化 this 对象. 因此, React 通过 Fiber 节点来存储和管理与函数组件相关的状态和生命周期.
  • 每个函数组件在每次渲染时, React 都会创建或更新与之对应的 Fiber 节点, Fiber 节点是 React 内部调度渲染的关键部分.

Fiber 节点中的关键信息

每个 Fiber 节点代表一个组件, 并包含以下关键信息:

  • tag: 表示 Fiber 组件的类型,例如 Function 组件和 class 组件。
  • key: 组件的 key 属性,用于在 diff 算法中帮助识别组件的唯一性。
  • elementType: 代表组件的类型,特定情况下(如被 React.memo 包裹时)可能与 type 不同。
  • type: 指向组件的类型,对于函数组件是函数本身,对于类组件是类,对于 DOM 节点是其 tagName。
  • stateNode: Fiber 对应的实际 DOM 节点的引用。
  • return: 指向父 Fiber 节点,形成 Fiber 树的链接关系。
  • child: 指向子 Fiber 节点,维护组件树的层级结构。
  • sibling: 指向同一层级的下一个兄弟 Fiber 节点。
  • index: 当前节点在兄弟节点中的位置索引。
  • pendingProps: 当前组件的属性,表示本次渲染的最新属性。
  • memoizedProps: 指向最近一次使用的 props,用于比较和更新。
  • updateQueue: 保存需要处理的更新信息的队列。
  • memoizedState: 组件的状态,用于保存当前状态值。
  • dependencies: 指向依赖于该组件的其他组件或数据。
  • mode: 表示组件运行的模式(并发模式或遗留模式),影响组件的更新方式。
  • flags: 当前组件的标记位,表示需要执行的操作(如更新、删除等)。
  • subtreeFlags: 当前组件子树的标记位,用于跟踪子组件的状态。
  • deletions: 保存需要删除的 Fiber 对象链表,以便在提交时处理。
  • lanes: 当前组件的调度优先级,用于调度更新任务。
  • childLanes: 子组件的优先级,表示在当前 Fiber 节点下的子组件的优先级。
  • alternate: 指向该 Fiber 在另一次更新时对应的 Fiber,允许 React 在更新过程中重用 Fiber 结构。

Fiber 如何管理函数组件

函数组件没有类组件中的实例, 因此 React 通过 Fiber 来管理函数组件的状态、Hooks 等信息:

  • useState 与 Fiber:useState 会将状态信息记录在与该组件对应的 Fiber 节点中, 每次状态更新时, React 会更新该节点.
  • useEffect 与 Fiber:useEffect 的副作用函数同样会被绑定到当前的 Fiber 节点上, 等待适当时机执行.

React Fiber 的工作原理

React 的渲染分为两个阶段:协调阶段 (Render Phase)提交阶段 (Commit Phase).

  1. 协调阶段 (Render Phase)
    • 在这个阶段, React 会遍历 Fiber 树, 比较新旧虚拟 DOM, 创建新的 Fiber 节点, 并标记需要更新的部分. 这个阶段是可中断的, React 可以在任务之间暂停, 处理更高优先级的任务.
  2. 提交阶段 (Commit Phase)
    • 提交阶段是不可中断的, React 会将协调阶段收集到的更改应用到真实 DOM 上, 并执行 useLayoutEffect 等同步副作用.

React Fiber 的关键特性

  • 任务优先级调度React Fiber 根据任务的优先级, 灵活安排更新任务, 确保更紧急的任务 (如用户输入) 优先处理.
  • 异步渲染:通过将渲染工作分割成更小的任务, React 可以在多个帧中完成渲染, 避免主线程长时间被占用.
  • 时间分片React Fiber 可以将大任务拆分为时间片, 在每个时间片内执行一部分任务, 使得 UI 渲染更流畅.

总结

  • 每个 React 函数组件与一个 Fiber 节点密切关联, 该节点用于调度和管理组件的渲染过程.
  • FiberReact 内部的核心数据结构, 追踪组件的状态、属性、DOM 引用等信息.
  • React Fiber 通过分割渲染任务、调度任务优先级, 优化了复杂 UI 场景下的性能和响应速度.

React Fiber 的引入大幅提升了 React 在复杂应用中的性能表现, 同时为实现并发渲染奠定了基础.