Fiber 是 React 的协调算法,在 React 16 中引入以取代之前的堆栈协调器。本文档解释了 Fiber 的架构、其内部工作原理以及它如何支持并发渲染和增量更新等特性。有关 Fiber 如何与特定渲染器交互的信息,请参阅 React DOM。
Fiber 既是一种数据结构,也是一种架构,它允许 React 实现以下功能:
Fiber 的核心设计原则是使渲染可中断,从而使 React 能够并发处理多个任务,并提供更好的用户体验,尤其是在复杂应用中。
来源
从核心来看,Fiber 是一个 JavaScript 对象,代表一个组件、其输入和输出。它充当一个工作单元,并捕获组件的状态和 DOM。
Fiber 结构的关键点
来源
React Fiber 引入了一个“工作循环”,用于控制 Fiber 树的遍历并执行工作。该循环可以被中断,从而允许浏览器处理高优先级事件。
此实现的核心部分在 ReactFiberWorkLoop.js 中,它定义了几个关键的执行上下文
在处理过程中,React 会跟踪当前执行上下文,以了解其所处的阶段,这对于在可中断渲染期间保持正确行为至关重要。
来源
Fiber 使用双缓冲技术来构建新的树(workInProgress),同时保持当前已渲染的树不变。这种方法允许 React 在不影响用户界面的情况下在后台准备新工作。
current 和 workInProgress Fiber 通过 alternate 属性连接,形成对,从而促进了这种双缓冲方法
此方法在以下文件中实现:
来源
React 的 Fiber 架构将工作分为两个主要阶段:
在此阶段,React 会进行以下操作:
重要提示:此阶段不产生任何可见更改——它仅构建“进行中”的树并计算需要更改的内容。
提交阶段具有以下特点:
提交阶段进一步分为子阶段:
来源
在构建或更新 Fiber 树时,React 遵循两阶段过程:
开始阶段(自上而下):
beginWork,它返回下一个要处理的子节点完成阶段(自下而上):
completeWork 以完成 Fiber 的最终化在处理 Fiber 时,React 可能会发现:
每种情况都以不同方式处理,并在 Fiber 上设置相应的标志。
来源
Fiber 引入了一种复杂的更新优先级系统,使用“车道”(lanes)(它取代了早期的“过期时间”模型)。车道在一个位字段中表示优先级和批处理。
更新会安排在特定的车道中,React 按照优先级顺序处理它们。多个更新可以在同一个车道中进行批处理。
调度系统支持以下功能:
来源
Fiber 使用标志和列表的组合来跟踪副作用(例如,DOM 更新、生命周期方法、ref)。副作用在渲染阶段收集,并在提交阶段执行。
在提交阶段,副作用以特定顺序应用,以确保正确行为:
来源
React Hooks 是在 Fiber 架构之上实现的。每个 Fiber 都有一个 memoizedState 字段,对于函数组件而言,它存储了一个 Hook 的链表。
每个 Hook 使用此链表结构在渲染之间维护其状态。当函数组件渲染时:
Hook 调用在渲染之间严格顺序的强制执行依赖于此链表结构。
来源
Fiber 的强大功能之一是能够暂停渲染,并在之后从中断处恢复。这支持了以下特性,例如:
当一个组件暂停(抛出一个 Promise)时:
来源
Fiber 包含强大的错误处理机制,用于捕获和通过组件树传播错误
当渲染过程中发生错误时,React 会进行以下操作:
在提交阶段:
此机制确保应用程序某一部分的错误不会破坏整个 UI。
来源
核心协调算法决定了哪些内容已更改并需要更新
对于子节点协调,React 使用键匹配和启发式算法来确定哪些元素与前一次渲染中的哪些 Fiber 对应。
来源
Fiber 内置了用于性能分析和调试的性能追踪功能
该架构在协调和渲染的各个阶段提供了 Hook,用于收集性能数据,使 React DevTools 等工具能够提供详细的可视化。
来源
Fiber 架构代表了 React 内部算法的彻底重构,旨在实现并发、增量更新和优先级管理。它建立在以下核心原则之上:
这种架构为 React 的许多高级特性提供了动力,包括并发模式、Suspense 和 Hooks API。它使 React 即使对于频繁更新的复杂应用程序也能提供响应式的用户体验。