跳到主要内容

一、React Fiber 架构

React Fiber 是 React 16+ 引入的协调引擎,代替了旧的栈调和( stack reconciler )。其核心目标是将不可中断的长任务拆分为可中断的增量任务,提升应用响应速度。

Fiber 架构的核心结构: Fiber 节点

每个元素对应一个 Fiber 节点,储存组件的类型 、 状态( state/props ) 、 副作用(如 DOM 更新) 、 子节点/兄弟节点等信息。Fiber 树(工作进度树)通过链表结构连接所有的 Fiber 节点,支持增量遍历。

提示

与旧的树形递归结构不同, Fiber 将组件树构建成一个链表。每个 Fiber 通过 return (执行父节点) 、 child (指向第一个子节点) 、 sibling(执行下一个兄弟节点)指针连接起来。这种结构使得 React 可以 增量地遍历树,而不是一次性递归到底。

Fiver 架构图关键流程:

  • 协调阶段
  • 提交阶段
  • 调度器

1. 协调阶段( Reconciliation ,可中断)

这个阶段的主要任务是构建新的 workInProgress 树,并与 current 树进行比较( Diff ) Props/state ,计算出需要更新的节点(标记为增、删、改等副作用)。

使用 requestIdleCallbackrequestAnimationFrame 拆分任务,每完成一个 Fiber 节点检测是否有更高优先级任务(如用户输入),若有则打断当前任务,保留进度后继续。

  • 特点 :此阶段是纯计算,不涉及任何真实 DOM 操作,因此可以被中断、暂停或丢弃
  • 过程React 会遍历 Fiber 链表,逐个处理工作单元。如果发现有更高优先级的任务(如用户输入),它会暂停当前的渲染工作,优先处理紧急任务,处理完再回来继续

2. 提交阶段( Commit ,不可中断)

当协调阶段完成后,所有需要进行的 DOM 变更都已经计算完毕。提交阶段的任务就是将这一些变更一次性、原子化应用到真实 DOM 上。

  • 特点 :此阶段不可中断
  • 原因 :为了保证 UI 的一致性。如果提交过程被中断,用户可能看到新旧数据混合的、不一致的画面
  • 过程 :主要包括 getSnapshotBeforeUpdate 生命周期、进行真实 DOM 操作(插入、更新、删除)、执行 useLayoutEffectcomponentDidMount/Update

3. 调度器

  • 管理任务列表,根据优先级决定执行顺序
  • 使用 requestIdleCallbackMessageChannel 实现任务分片

二、Fiber 解决的核心问题

1. 可中断更新( Incremental Rendering)

旧版栈调和(Stack Reconciler)使用递归遍历组件树,一旦开始无法中断。若组件庞大,长任务会阻塞主线程,导致页面卡顿(如输入延迟 、 动画掉帧)。

Fiber 通过将任务拆分为微任务单元(每个 Fiber 节点为一个单元),利用浏览器的空余时间(requestIdleCallback)或时间切片(requestAnimationFrame)执行。每完成一个单元,检测是否有更高级优先级的任务(如用户交互),若有则暂停当前任务并保存进度(通过 Fiber 节点的链表结构记录当前处理位置),后续恢复时执行。

2.优先级调度( Priority Scheduling )

Fiber 为不同类型的更新分配了优先级(如用户输入事件 > 数据加载 > 列表渲染)。高优先级任务可中断第优先级的任务,确保关键操作(如按钮点击)快速响应。

  • Immediate:用户输入 、 错误处理,立即执行
  • UserBlocking:动画 、 点击状态变化,尽快执行
  • Normal:数据请求后的列表渲染,可中断
  • Low/Idle:非关键日志 、 延迟加载,低优先级执行

三、双缓存树( Double Buffering )

Fiber 使用双缓存技术管理 Fiber 树,解决“如何高效生成下一帧 UI ”的问题。

1. 双缓存树的定义

  • 当前树( Current Tree:对应当前屏幕显示的 UI ,已完成提交状态
  • 工作进度树( WorkInProgress Tree:正在协调阶段构建的下一帧 UI 树

2. 工作流程

  • 初始时,current tree 指向当前树
  • 当需要更新时,基于 current tree 的 Fiber 节点克隆生成 workInProgress tree (浅拷贝,复用大部分节点)
  • 协调阶段修改 workInProgress tree 的属性(如更新 state),标记副作用
  • 提交阶段完成后,workInprogress tree 变成新的 current tree (通过指针交换),旧 current tree 变成为下一次的 workInProgress tree(节点被复用)

3. 优势

  • 减少内存开销:复用 Fiber 节点,避免频繁创建/销毁对象
  • 可中断:如果构建过程被打断,可以安全地丢弃 WorkInprogress Tree
  • 高效切换:通过指针交换快速完成切换,无需重新构建整棵树

四、为什么需要 Fiber

根本原因是前端应用的复杂度提升,旧版栈调和无法满足性能条件:

  • 长时间阻塞主线程:栈调和的递归特性导致无法中断,复杂组件树可能会导致页面的卡断(如滚动时延迟输入)
  • 缺乏优先级控制:所有的更新按顺序执行,低优先级任务(如列表渲染)可能阻塞高优先级任务(如用户点击)
  • 无法感知任务耗时:无法统计单个组件的渲染时间,难以针对性优化

Fiber 通过以下方式解决:

  • 可中断的增量渲染:将长任务拆分为微任务,避免阻塞主线程
  • 优先级调度:确保关键任务优先执行,提升用户体验
  • 双缓存树:高效生成下一帧 UI,减少内存和计算开销

且 Fiber 支持

  • 并发特性 :为 SuspenseTime Slicing 等特性提供底层支持,例如异步加载组件时保持洁面响应
  • 错误边界和调试
    • 每个 Fiber 节点可捕获子树错误,避免整个应用奔溃
    • 支持时间旅行,优化开发者工具体验