深入理解React的Fiber架构

 更新时间:2026年05月11日 09:27:20   作者:秀秀不只会前端  
本文简要介绍了Fiber的核心概念、数据结构、架构原理及其在React中的作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Fiber 的核心目标——把一次“不可中断的递归渲染”,拆成“可中断、可恢复、可优先级调度的工作单元”

一、为什么 React 要引入 Fiber?

老架构(Stack Reconciler)的问题,React 16 之前:

  • diff + render 是一次性同步递归
  • JS 线程被长期占用
  • 浏览器:
    • ❌ 不能响应用户输入
    • ❌ 不能渲染动画
    • ❌ 会卡顿、掉帧

📌 本质问题:React 没法“暂停 / 打断 / 恢复”渲染

二、核心概念

Fiber 是 React 内部对“组件/DOM 节点”的一种可调度的执行单元(Work Unit)

不是虚拟 DOM 本身,而是:

  • 虚拟 DOM + 运行时控制信息
  • 数据结构 + 执行上下文

三、Fiber 的核心数据结构

一个 Fiber 本质是一个对象:

interface Fiber {
  // 节点类型
  tag: WorkTag;

  // 对应的组件或 DOM
  type: any;
  stateNode: any;

  // Fiber 树结构
  return: Fiber | null;  // 父
  child: Fiber | null;   // 第一个子
  sibling: Fiber | null; // 下一个兄弟

  // 状态相关(Hooks 在这)
  memoizedState: any;
  updateQueue: UpdateQueue<any> | null;

  // props
  pendingProps: any;
  memoizedProps: any;

  // 副作用
  flags: Flags;
  subtreeFlags: Flags;

  // 双缓存
  alternate: Fiber | null;
}

一些关键点:

  1. 树结构是 链表式的,为了能中断遍历,而不是递归调用栈
child → sibling → sibling
  1. alternate:Fiber 的灵魂,“并发渲染不撕裂 UI”的关键
current Fiber  ←→  workInProgress Fiber
  • current:当前屏幕显示的
  • wip:正在计算的新版本
  1. Hooks 存在哪里?useState 不是存在闭包,而是存在 Fiber 上
fiber.memoizedState // Hooks 单向链表

四、Fiber 架构下的两大阶段

这两个阶段正是组件渲染的两个阶段:

  1. 父组件渲染导致子组件渲染(默认行为)
  2. 组件内状态更新
  3. context 改变导致使用 useContext 的组件更新

1️⃣ Render 阶段(Reconciliation 协调阶段)

做什么?

  • 创建 / 复用 Fiber(diff 过程)
  • 执行函数组件
  • 计算新 state,运行 useState,useMemo,useCallback
  • 标记副作用(flags),生成更新链表

特点:

  • ✅ 可打断
  • ❌ 不操作 DOM
  • ❌ 不执行副作用

beginWork
  ↓
completeWork

2️⃣ Commit 阶段(提交阶段 / 实际 DOM 操作)

分三步:

  1. before mutation(提交前)

执行:

  • getSnapshotBeforeUpdate
  • 调整内容前的准备
  1. mutation(变更 DOM)

执行所有 DOM 操作:

  • 插入 DOM
  • 删除 DOM
  • 修改 DOM 属性
  • ref 的更新
  1. layout(布局阶段)

执行 Layout Effects:

  • useLayoutEffect 回调
  • class 组件的 componentDidMount / componentDidUpdate

Mutation 和 Layout 这两步是同步执行的,不允许中断。

总结下,上述做了什么?

  • 更新 DOM
  • 执行 useEffect / useLayoutEffect(componentDidMount)
  • ref 赋值

特点:

  • ❌ 不可中断
  • ✅ 必须一次完成

Render 阶段算账,Commit 阶段交付

state 更新 / props 更新 / context 更新
        ↓
---- Render 阶段(可中断) ----
1. 执行组件函数
2. 运行 hooks
3. 生成新的 Fiber 树
4. 计算 diff
5. 构建 effectList(DOM 变更清单)
        ↓
---- Commit 阶段(不可中断) ----
1. before mutation(DOM 操作前的准备)
2. mutation(真实 DOM 更新)
3. layout(执行 useLayoutEffect、componentDidMount)
        ↓
浏览器绘制(paint)
        ↓
最后执行 useEffect(异步)

五、Fiber 是如何实现“可中断”的?

核心思想:时间切片(Time Slicing)

React 不再:

renderTree(); // 一口气干完

而是:

while (还有时间 && 还有任务) {
  执行一个 Fiber
}

如果:

  • 浏览器要绘制
  • 用户输入
  • 高优先级任务来了

那么,React 暂停当前 Fiber,稍后恢复。

Fiber 为什么能恢复?

因为 Fiber 本身就保存了:

  • 执行到哪了
  • 子节点处理到哪
  • 副作用信息

六、优先级调度(Scheduler)

不同更新优先级不同:

React 可以:

  • 丢弃低优先级渲染
  • 重做高优先级渲染
  • 但 UI 不会乱

七、一次 setState 的 Fiber 流程

setCount(c => c + 1);

内部流程:

  1. 创建 update
  2. 挂到 Fiber.updateQueue
  3. 根据优先级调度
  4. 创建 workInProgress Fiber
  5. render 阶段计算新 state(state 永远只在 Fiber 上变)
  6. 标记 flags
  7. commit 阶段更新 DOM

八、和 Vue 响应式的根本差异

Vue:数据驱动更新 React:调度驱动更新

Vue:

state.x = 1 → 精确更新

React:

setState → 重新执行组件

Fiber 的存在,是 React 能做到并发的前提。

九、如何实现“并发”?

React 并发(Concurrent)不是多线程,而是:在单线程 JS 中,把一次渲染拆成可中断、可重试、可丢弃的任务调度模型。

⚠️ React 并发 ≠ Promise ≠ async/await ≠ Web Worker

并发的是 “渲染任务的调度权”,React 可以在多个“未完成的渲染版本”之间来回切换。

本质上就是通过 双 Fiber 树 + render/commit 分离 + scheduler 调度器 ​实现的。

并发特性​是否生效​,取决于:

  • useTransition
  • useDeferredValue
  • Suspense
  • 更新优先级

scheduler 调度器 体现在开发层面是指 useTransition、useDeferredValue、Suspense 等。

这些都是并发

1️⃣ 可中断(Interruptible)

渲染到一半 →
  浏览器要绘制 →
    React 暂停 render

2️⃣ 可重试(Restartable)

低优先级渲染中 →
  高优先级更新来了 →
    丢弃当前渲染 →
      从头再算

3️⃣ 可丢弃(Discardable)

用户连续输入 →
  前面几次渲染直接废弃

最终只 commit“最后一次正确结果”

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

相关文章

  • 浅谈react新旧生命周期钩子

    浅谈react新旧生命周期钩子

    所谓的生命周期就是指某个事物从开始到结束的各个阶段,本文主要介绍了浅谈react新旧生命周期钩子,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • react中的useEffect()的使用详解

    react中的useEffect()的使用详解

    useEffect()是react中的hook函数,作用是用于创建由渲染本身引起的操作,介绍了依赖项数组不同的区别,对react useEffect()使用相关知识感兴趣的朋友一起看看吧
    2024-05-05
  • create-react-app常用自定义配置教程示例

    create-react-app常用自定义配置教程示例

    这篇文章主要为大家介绍了create-react-app常用自定义配置教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • React报错map() is not a function详析

    React报错map() is not a function详析

    这篇文章主要介绍了React报错map() is not a function详析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • react 通过后端接口实现路由授权的示例代码

    react 通过后端接口实现路由授权的示例代码

    本文主要介绍了React应用中通过后端接口获取路由授权,实现动态和灵活的权限管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • React中的Refs属性你来了解吗

    React中的Refs属性你来了解吗

    这篇文章主要为大家详细介绍了的React Refs属性,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • React组件实例三大属性state props refs使用详解

    React组件实例三大属性state props refs使用详解

    这篇文章主要为大家介绍了React组件实例三大属性state props refs使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • React-View-UI组件库封装Loading加载中源码

    React-View-UI组件库封装Loading加载中源码

    这篇文章主要介绍了React-View-UI组件库封装Loading加载样式,主要包括组件介绍,组件源码及组件测试源码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • React中props使用教程

    React中props使用教程

    props是组件(包括函数组件和class组件)间的内置属性,用其可以传递数据给子节点,props用来传递参数。组件实例化过程中,你可以向其中传递一个参数,这个参数会在实例化过程中被引用
    2022-09-09
  • React组件通信实现流程详解

    React组件通信实现流程详解

    这篇文章主要介绍了React组件通信,在开发中组件通信是React中的一个重要的知识点,本文通过实例代码给大家讲解react中常用的父子、跨组件通信的方法,需要的朋友可以参考下
    2022-12-12

最新评论