React的Fiber架构

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

一、为什么 React 要引入 Fiber?

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

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

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

二、核心概念

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

不是虚拟 DOM 本身,而是:

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

三、Fiber 的核心数据结构

一个 Fiber 本质是一个对象:

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

四、Fiber 架构下的两大阶段

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

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

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

做什么?

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

特点:

  • ✅ 可打断
  • ❌ 不操作 DOM
  • ❌ 不执行副作用
Plain 复制代码
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 阶段交付

Plain 复制代码
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 不再:

JavaScript 复制代码
renderTree(); // 一口气干完

而是:

JavaScript 复制代码
while (还有时间 && 还有任务) {
  执行一个 Fiber
}

如果:

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

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

Fiber 为什么能恢复?

因为 Fiber 本身就保存了:

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

六、优先级调度(Scheduler)

不同更新优先级不同:

React 可以:

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

七、一次 setState 的 Fiber 流程

JavaScript 复制代码
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:

JavaScript 复制代码
state.x = 1 → 精确更新

React:

JavaScript 复制代码
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)
Plain 复制代码
渲染到一半 →
  浏览器要绘制 →
    React 暂停 render
2️⃣ 可重试(Restartable)
Plain 复制代码
低优先级渲染中 →
  高优先级更新来了 →
    丢弃当前渲染 →
      从头再算
3️⃣ 可丢弃(Discardable)
Plain 复制代码
用户连续输入 →
  前面几次渲染直接废弃

最终只 commit"最后一次正确结果"

相关推荐
初恋叫萱萱几秒前
技术基石与职场进阶:构建从Web后端到高性能架构的完整知识图谱
前端·架构·知识图谱
lpfasd1231 分钟前
Nacos 实战指南:构建安全、高可用的微服务注册与配置中心
安全·微服务·架构
木木木一4 分钟前
Rust学习记录--C9 错误处理
前端·学习·rust
刘一说5 分钟前
微服务配置中心:从痛点到实践——Nacos深度应用指南
spring boot·spring cloud·微服务·云原生·架构
局外人LZ6 分钟前
libsodium.js:web端与 Node.js 的现代加密工具集,构建前端安全加密体系
前端·javascript·node.js
哈__8 分钟前
React Native 鸿蒙跨平台开发:ToastAndroid 提示消息
react native·react.js·harmonyos
龙亘川9 分钟前
政务数据赋能数字政府:7 大场景 + 3 大标杆案例的技术实现与架构拆解
架构·政务
Yeats_Liao11 分钟前
昇腾910B与DeepSeek:国产算力与开源模型的架构适配分析
人工智能·python·深度学习·神经网络·机器学习·架构·开源
xkxnq11 分钟前
第二阶段:Vue 组件化开发(第 20天)
前端·javascript·vue.js
哈__15 分钟前
React Native 鸿蒙跨平台开发:Keyboard 键盘控制
javascript·react native·react.js