深入理解React Fiber机制

 更新时间:2026年06月11日 08:19:42   作者:卷帘依旧  
React Fiber 是 React 16 引入的核心协调算法重构,它解决了旧版 Stack Reconciler 的不可中断、同步递归导致的卡顿问题,下面就来详细的介绍一下

React Fiber 是 React 16 引入的核心协调算法重构,它解决了旧版 Stack Reconciler 的不可中断、同步递归导致的卡顿问题。

简单来说:Fiber 让 React 的渲染过程从「一口气干完」变成了「可中断、可分片、可优先级排序」的任务调度。

下面从三个关键维度展开:

一、为什么需要 Fiber?(痛点分析)

旧版 React(<16)的 Stack Reconciler 有致命缺陷:

  • 同步递归:遍历整个虚拟 DOM 树时,一旦开始就无法停止。
  • 阻塞主线程:如果组件层级很深(几百个),一次更新可能占用 100ms+ 的 JS 执行时间。
  • 导致掉帧:浏览器需要 16.6ms 渲染一帧(60fps),而 React 长期霸占主线程,用户点击、动画都会卡顿。

典型案例:一个输入框绑定大列表更新,每次按键都重新渲染整个列表,造成明显延迟。

Fiber 的目标就是:把同步不可中断的工作,拆解成异步可中断的小任务单元

二、Fiber 的核心机制

1. Fiber 是什么?(数据结构 + 工作单元)

Fiber 既是数据结构,也是执行单元

作为数据结构:每个 React 元素对应一个 Fiber 节点,构成 Fiber 树(链表结构,而非树)。

// Fiber 节点的核心字段
{
  tag: 5,               // 节点类型(函数组件、类组件、DOM等)
  key: null,
  type: 'div',
  return: parentFiber,  // 指向父 Fiber(完成后的返回目标)
  child: childFiber,    // 指向第一个子 Fiber
  sibling: siblingFiber,// 指向下一个兄弟 Fiber
  pendingProps: {},     // 新传入的 props
  memoizedProps: {},    // 上次渲染的 props
  memoizedState: null,  // 上次渲染的 state(用于 Hooks)
  alternate: null,      // 双缓存中的另一个 Fiber(current <-> workInProgress)
}

作为执行单元:Fiber 节点记录了自身的「进度信息」,React 可以在中断后从任意 Fiber 继续工作。

2. 双缓存机制(Double Buffering)

React 维护两棵 Fiber 树:

  • current 树:当前屏幕上显示的内容(已提交到 DOM)。
  • workInProgress 树:在内存中构建的新树,代表下一次要显示的界面。

工作流程:

  1. 触发更新时,克隆 current 树生成 workInProgress 树。
  2. 在 workInProgress 树上进行协调(diff + 标记副作用)。
  3. 构建完成后,commitRoot 将 workInProgress 树切换为 current 树(一次指针切换)。
  4. 复用 alternate 属性指向另一棵树,节省内存分配。

好处:可以在构建过程中随时放弃 workInProgress 树,不影响用户当前看到的界面。

3. 调度与优先级(Scheduler)

Fiber 搭配了独立的调度器(Scheduler),实现了时间切片和优先级队列。

  • 任务拆分:将协调过程拆解为多个「工作单元」(每个 Fiber 节点的处理就是一个单元)。
  • 时间切片:每次循环检查是否还有剩余时间(shouldYield),超时则中断并让出主线程。
  • 优先级机制
    • 离散事件(click、input):立即同步执行(最高优先级)。
    • 连续事件(scroll、拖拽):下一帧之前执行(高优先级)。
    • 数据请求(useEffect、Suspense fallback):可中断的低优先级
    • startTransition 标记的更新:最低优先级,空闲时执行。

简单模拟调度流程:

// 简化的 workLoop
function workLoop(deadline) {
  let shouldYield = false;
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(nextUnitOfWork); // 处理一个 Fiber
    shouldYield = deadline.timeRemaining() < 1;         // 剩余时间不足 1ms 则中断
  }
  if (nextUnitOfWork) {
    requestIdleCallback(workLoop); // 有空闲时间再继续
  } else {
    commitRoot(); // 全部完成,提交 DOM
  }
}
requestIdleCallback(workLoop);

三、Fiber 架构下的两个阶段

React 将渲染过程拆解为两个截然不同的阶段:

阶段执行内容是否可中断是否执行副作用常见方法
Render/Reconciliation构建 Fiber 树、计算 diff、标记副作用✅ 可中断rendershouldComponentUpdate、hooks 中的更新计算
Commit将副作用应用到真实 DOM、执行生命周期❌ 不可中断componentDidMountuseLayoutEffectref 更新

重要区别

  • Render 阶段可以被打断(比如用户点击新的高优先级事件),React 会丢弃当前 workInProgress 树,重新开始。
  • Commit 阶段必须同步完成,确保 DOM 一致性和用户看到的结果。

这也解释了为什么 componentWillMountcomponentWillUpdate 被标记为不安全 —— 它们可能在 Render 阶段被多次调用或中断。

四、Fiber 带来的具体能力

  1. Concurrent Mode(并发模式,现为默认启用):渲染和用户输入并行处理,不再互相阻塞。
  2. Suspense:等待异步数据(代码、图片、数据)时,渲染 fallback,数据就绪后继续 Fiber 工作。
  3. useDeferredValue / startTransition:将低优先级更新标记为可中断,保障高优先级响应的流畅度。
  4. 错误边界:通过 componentDidCatch 捕获子组件树的错误,防止整个应用崩溃。

五、常见面试追问与简答

Q:Fiber 架构下的 diff 算法有变化吗?
A:核心策略相同(同级比较、key 复用),但实现上基于 Fiber 链表,且 diff 过程是异步可中断的。

Q:Fiber 有打破 React 声明式编程的范式吗?
A:没有。Fiber 是内部实现优化,对外 API 保持一致,开发者依然面向状态编程。

Q:使用 Fiber 一定能提升性能吗?
A:不一定。对于简单应用,Fiber 的调度开销可能略微增加总耗时。主要收益是在复杂交互场景(输入框 + 大列表渲染)下保持 UI 流畅。

Q:Fiber 树和虚拟 DOM 树是什么关系?
A:虚拟 DOM 是 React 元素树(每次 render 重建)。Fiber 树是持久化的(只更新属性),通过 alternate 复用节点,性能更高。

如果你需要进一步了解 Fiber 的副作用收集(Effect List)Hooks 在 Fiber 上的存储原理,我可以继续展开。

到此这篇关于深入理解React Fiber机制的文章就介绍到这了,更多相关React Fiber 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React state状态属性详细讲解

    React state状态属性详细讲解

    React将组件(component)看成一个状态机(State Machines),通过其内部自定义的状态(State)和生命周期(Lifecycle)实现并与用户交互,维持组件的不同状态
    2022-09-09
  • React使用ref方法与场景介绍

    React使用ref方法与场景介绍

    这篇文章主要介绍了React使用ref方法与场景,React支持给任意组件添加特殊属性。ref属性接受一个回调函数,它在组件被加载或卸载时会立即执行
    2022-10-10
  • 创建React项目的三个方式小结

    创建React项目的三个方式小结

    本文主要介绍了创建React项目的三个方式小结,包括create-react-app、Vite和Next.js,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2025-07-07
  • 详解React的回调渲染模式

    详解React的回调渲染模式

    这篇文章主要介绍了详解React的回调渲染模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • react-native 圆弧拖动进度条实现的示例代码

    react-native 圆弧拖动进度条实现的示例代码

    本篇文章主要介绍了react-native 圆弧拖动进度条实现的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • react如何实现表格多条件搜索

    react如何实现表格多条件搜索

    这篇文章主要介绍了react如何实现表格多条件搜索问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • react native 文字轮播的实现示例

    react native 文字轮播的实现示例

    这篇文章主要介绍了react native 文字轮播的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • React函数组件和类组件的区别及说明

    React函数组件和类组件的区别及说明

    这篇文章主要介绍了React函数组件和类组件的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 详解在create-react-app使用less与antd按需加载

    详解在create-react-app使用less与antd按需加载

    这篇文章主要介绍了详解在create-react-app使用less与antd按需加载,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • React memo减少重复渲染详解

    React memo减少重复渲染详解

    React.memo为高阶组件。它与React.PureComponent 非常相似,但它适用于函数组件,但不适用于class组件。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-10-10

最新评论