第 41 期 - React 16 中 Fiber 架构提升性能的原理
logoFRONTALK AI/12月3日 16:31/阅读原文

摘要

通过对比 React 15 和 React 16 的架构差异,阐述了 React 16 中 Fiber 架构在异步渲染和优先级调度方面的原理,包括 Fiber 架构的三层含义、工作原理及双缓存技术等内容,解释了其如何提升页面加载和用户交互流畅性。

一、React 不同版本效果对比及原因

首先文章给出了 React 15.7 版本和 React 16.8 版本的两个例子,在相同操作下,React 16.8 版本比 React 15.7 版本更流畅。这是因为 React 15 每次调用this.setState会重新渲染整个组件树,在componentDidMount中调用相关方法会触发大量JS运算,占住主线程,导致页面卡顿和用户输入无响应。而 React 16 引入了Fiber架构,采用异步更新策略,把update拆分成多个小块在多个事件循环周期内完成,优先渲染高优先级更新,避免阻塞主线程。

二、React 15 架构

(一)Reconciler(协调器)

在 React 15 中,可通过this.setStatethis.forceUpdateReactDOM.render等 API 触发更新。更新时,Reconciler会调用组件的render方法将JSX转化为虚拟DOM,对比新旧虚拟DOM找出变化部分,再通知Renderer渲染。它没有优先级和中断机制,递归对比时会锁定页面。

// 假设这是一个简单的 React 15 组件示例
class MyComponent extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}

(二)Renderer(渲染器)

React 支持跨平台,不同平台有不同的Renderer,前端最熟悉的是浏览器环境下的ReactDOM。每次更新时,Renderer在接到Reconciler通知后将变化的组件渲染到宿主环境。

(三)React 15 架构的缺点

Reconciler中的mountComponentupdateComponent方法递归更新子组件,一旦层级过深且更新时间超 16ms,用户交互就会卡顿。且ReconcilerRenderer交替工作,在更新过程中用户输入不能马上响应。

三、React 16 架构

(一)Scheduler(调度器)

React 16 新增了Scheduler。原本可以使用浏览器的requestIdleCallback,但因兼容性、调度不精确、调试困难和不支持任务优先级等问题被放弃,于是 React 实现了requestIdleCallbackpolyfill也就是Scheduler,它除了空闲时触发回调功能外,还提供多种调度优先级。

// 简单示意 Scheduler 可能的使用逻辑
Scheduler.scheduleTask(() => {
  console.log('执行一个高优任务');
}, 'high');

(二)Reconciler(协调器)

React 16 的Reconciler将更新工作从递归变为可中断的循环过程,每次循环调用shouldYield判断是否有剩余时间。并且ReconcilerRenderer不再交替工作,Reconciler会为变化的虚拟DOM打标记,所有工作在内存中进行,全部完成后才交给Renderer

(三)Renderer(渲染器)

Renderer根据Reconciler为虚拟DOM打的标记同步执行对应的DOM操作。

四、Fiber 架构

(一)Fiber 的起源

React 15 及以前Reconciler采用递归创建虚拟DOM且不能中断,组件树层级深时会卡顿,为解决此问题,将递归更新重构为异步可中断更新,Fiber架构应运而生。

(二)Fiber 的含义

  1. 作为架构:React 15 的Reconcilerstack Reconciler(递归方式),React 16 的Reconciler基于Fiber节点实现,称为Fiber Reconciler
  2. 作为静态的数据结构:每个Fiber节点对应一个React element,保存组件类型、DOM节点等信息。
  3. 作为动态的工作单元:保存本次更新中组件改变的状态、要执行的工作等信息。Fiber节点包含很多属性,可按三层含义分类。
// Fiber 节点的示例结构
function FiberNode(tag, pendingProps, key, mode) {
  // 各种属性的定义
}

(三)Fiber 的工作原理

  1. 双缓存:React 中最多同时存在两棵Fiber树,当前屏幕显示内容对应的是current Fiber树,正在构建的是workInProgress Fiber树,它们通过alternate属性连接,通过current指针切换。
  2. mount 时:首次执行ReactDOM.render创建fiberRootrootFiberfiberRoot是整个应用根节点,rootFiber是组件树根节点。在render阶段构建workInProgress Fiber树并复用已有属性,commit阶段渲染到页面后,workInProgress Fiber树变为current Fiber树。
  3. update 时:状态改变时开启新的render阶段构建新的workInProgress Fiber树,复用current Fiber树节点数据,构建完成后在commit阶段渲染到页面并成为新的current Fiber树。

五、总结

React 16 引入的SchedulerFiber架构协同工作,Scheduler协调任务时间线,Fiber重新实现核心算法使渲染异步化,具备暂停、恢复和优先级调度能力,实现异步渲染和优先级调度,提升页面加载和用户交互的流畅性。

 

扩展阅读

Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有