Skip to content

React 技术揭秘

React 架构

  • Scheduler(调度器)—— 调度任务的优先级,高优任务优先进入Reconciler
  • Reconciler(协调器)—— 负责找出变化的组件
  • Renderer(渲染器)—— 将变化的组件渲染到页面上

Fiber实现原理

Fiber Principles

Fiber并不是计算机术语中的新名词,中文翻译叫做纤程,与进程(Process)、线程(Thread)、协程(Coroutine)同为程序执行过程。

React Fiber 可以理解为:React内部实现的一套状态更新机制。支持任务不同优先级,可中断与恢复,并且恢复后可以复用之前的中间状态。 其中每个任务更新单元为 React Element 对应的 Fiber节点

Fiber 结构

javascript
function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // 作为静态数据结构的属性
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null;

  // 用于连接其他Fiber节点形成Fiber树
  this.return = null;
  this.child = null;
  this.sibling = null;
  this.index = 0;

  this.ref = null;
  this.refCleanup = null;

  // 作为动态的工作单元的属性
  this.pendingProps = pendingProps;
  this.memoizedProps = null;
  this.updateQueue = null;
  this.memoizedState = null;
  this.dependencies = null;

  this.mode = mode;

  // Effects
  this.flags = NoFlags;
  this.subtreeFlags = NoFlags;
  this.deletions = null;

  // 调度优先级相关
  this.lanes = NoLanes;
  this.childLanes = NoLanes;

  // 指向该fiber在另一次更新时对应的fiber
  this.alternate = null;
}

每个Fiber节点有个对应的 React element,多个 Fiber节点 依靠如下属性连接形成树

JavaScript
// 指向父级Fiber节点
this.return = null;
// 指向子Fiber节点
this.child = null;
// 指向右边第一个兄弟Fiber节点
this.sibling = null;

静态的数据结构

保存组件相关信息

javascript
// Fiber对应组件的类型 Function/Class/Host...
this.tag = tag;
// key属性
this.key = key;
// 大部分情况同type,某些情况不同,比如FunctionComponent使用React.memo包裹
this.elementType = null;
// 对于 FunctionComponent,指函数本身,对于ClassComponent,指class,对于HostComponent,指DOM节点tagName
this.type = null;
// Fiber对应的真实DOM节点
this.stateNode = null;

Fiber工作原理

Fiber节点 可以保存对应的 DOM节点Fiber节点 构成的 Fiber树 就对应 DOM树

DOM 更新使用到了 双缓冲(在内存中构建并直接替换) 技术

双缓冲

双缓冲 即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。

React 使用 双缓冲 来完成 Fiber树 的构建与替换——对应着 DOM树 的创建与更新

双缓冲Fiber树

React 中最多会同时存在两棵 Fiber树
当前屏幕上显示内容对应的 Fiber树 称为 current Fiber树,正在内存中构建的 Fiber树 称为 workInProgress Fiber树

current Fiber树 中的 Fiber节点 被称为 current fiberworkInProgress Fiber树 中的 Fiber节点 被称为 workInProgress fiber,他们通过 alternate 属性连接。

javascript
  currentFiber.alternate === workInProgressFiber;
  workInProgressFiber.alternate === currentFiber;

React应用的根节点通过使 current指针 在不同Fiber树的 rootFiber 间切换来完成 current Fiber树 指向的切换。

即当 workInProgress Fiber树 构建完成交给 Renderer 渲染在页面上后,应用根节点的 current指针 指向 workInProgress Fiber树,此时 workInProgress Fiber树 就变为 current Fiber树

每次状态更新都会产生新的 workInProgress Fiber树,通过 currentworkInProgress 的替换,完成 DOM更新

workInProgress fiber 的创建可以复用 current Fiber 树对应的节点数据。(由diff算法决定是否复用)