React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React Fiber架构

深入理解React的Fiber架构

作者:秀秀不只会前端

本文简要介绍了Fiber的核心概念、数据结构、架构原理及其在React中的作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

一、为什么 React 要引入 Fiber?

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

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

二、核心概念

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

不是虚拟 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
  1. Hooks 存在哪里?useState 不是存在闭包,而是存在 Fiber 上
fiber.memoizedState // Hooks 单向链表

四、Fiber 架构下的两大阶段

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

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

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

做什么?

特点:

beginWork
  ↓
completeWork

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

分三步:

  1. before mutation(提交前)

执行:

  1. mutation(变更 DOM)

执行所有 DOM 操作:

  1. layout(布局阶段)

执行 Layout Effects:

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

总结下,上述做了什么?

特点:

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 可以:

七、一次 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 调度器 ​实现的。

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

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

这些都是并发

1️⃣ 可中断(Interruptible)

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

2️⃣ 可重试(Restartable)

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

3️⃣ 可丢弃(Discardable)

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

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

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

您可能感兴趣的文章:
阅读全文