什么????都 2025 年了不会还有前端不知道 Fiber 吧

143 阅读3分钟

为什么要有 Fiber

回答这个问题之前,先假设,如果没有 Fiber,现在的 React 会是怎么样的。聪明的人应该会想到,如果没有Fiber,那么 React 其实回归了 15 及之前的版本。它本身的调度机制存在以下几个问题

  1. 更新过程是同步不可中断.
    1. 当项目组件树过大,从深层的组件进行更新,必然会牵一发而动全身,导致页面卡顿甚至冻结(形成一个长任务,用户会有很明显的体感)。
  2. 没法很好的管理任务的优先级
    1. 任务没法打断,如果有一个高优先级的任务想先渲染呢?
    2. 打断后没法恢复

那么,React 使用 Fiber 其实很大意义上是为了解决以上的问题。

  1. 增量渲染
    1. 将任务拆分为多个小任务(可以理解成一个组件就对应一个 Fiber 节点)
    2. 引入时间分片机制,避免阻塞主线程。
  2. 可中断与恢复
    1. 高优先级任务(如用户点击)可中断低优先级任务(如数据渲染),待主线程空闲时再恢复,确保交互的即时响应。

什么是Fiber

这里直接看图吧

画板

这里通过图可以得到

  1. Fiber 实际上是一个 JS 中的类,只不过这个类里有很多属性,React 可以根据这些属性来实现相应的特性。
  2. 这个类是通过处理虚拟 DOM 得到的,并不是 React 直接处理的 JSX。

原理

这里不过多的分析详细的源码,直接从整体出发

画板

整个过程精简下来就图中的几个步骤,整个过程会通过一个scheduler进行调度,从而在几个时间片内生成最终的组件树,最后渲染到页面上。

回答上面的几个问题

  1. 增量渲染
    1. 原理就是,首先引入了时间片机制,进行分片渲染,将长任务变成段任务。
    2. 引入 Fiber,一个 Fiber 代表一个组件,所以就从处理整颗组件树变成了处理一个一个的 Fiber,最后再将 Fiber 组合。
  2. 可中断与恢复
    1. scheduler在调度的时候,是会判断新任务和当前任务的优先级的,如果优先级不够,是会直接打断旧任务,执行优先级高的任务。
    2. React 最后渲染的是一个 Fiber 树,而 Fiber 树采取增量构造的过程,每次构造的树会挂载 Fiber 树上。所以下一次任务恢复的时候,会继续在中断的地方开始渲染。就实现了可恢复的特性。

聊点高级的

  1. React18 引入了useDeferredValue以及useTransition,其本质是利用了 Fiber 优先级 lane 的概念,从而划分出一批低优先级的更新, 让高优先级的更新先渲染,就实现了这个概念。 具体的可以单独出一篇文档讲一下。