React16_Fiber


React16_Fiber

Fiber是什么

可简单认为是,以链表结构相连的 虚拟DOM,同时挂载了 组件状态和更新操作

一种架构名称 : React16的Reconciler基于Fiber节点实现,被称为Fiber Reconciler。

React15的Reconciler采用递归的方式执行,数据保存在递归调用栈中,所以被称为stack Reconciler。

一种数据结构名称 : 一个Fiber节点对应一个React element,包含组件的类型,虚拟DOM、真实DOM等信息。

React的最小工作单元 : 运行时,Fiber 储存了该组件改变的状态、要执行的操作(删除/插入/更新…)。

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.pendingProps = pendingProps;
    this.memoizedProps = null;
    this.updateQueue = null;
    this.memoizedState = null;
    this.dependencies = null;

    this.mode = mode;

    this.effectTag = NoEffect;
    this.nextEffect = null;

    this.firstEffect = null;
    this.lastEffect = null;

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

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

React技术揭秘–Fiber的结构

Fiber的工作原理(Fiber树篇)

帧动画绘制时会采用 双缓存 机制,在内存中绘制帧,再直接替换当前帧,减少白屏.

Fiber架构模拟了双缓存机制

React存在两颗Fiber树,当前页面内容对应的 current Fiber树, 内存中构建的 workInProgress Fiber树

workInProgress Fiber树构建完成交给Renderer渲染,

应用根节点的current指针指向workInProgress Fiber树workInProgress Fiber树就变为current Fiber树

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

在内存中构建树,可随时终止更新,让渡浏览器主线程,构建完毕一次性commit渲染视图

current Fiber树 节点为 current fiber,workInProgress Fiber树 节点为 workInProgress fiber,他们通过alternate属性连接。

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

mount 与 update 流程

mount时,

ReactDOM.render 会创建 fiberRoot 应用根节点,其 current 指向 当前页面内容对应的 current Fiber树.

render阶段,在内存中 依组件次序 各自创建 虚拟DOM转换为 Fiber,连接构成Fiber树,此时为 workInProgress Fiber树.

render阶段,构建 workInProgress Fiber树 时会尝试复用 current Fiber树 中已有的Fiber节点内的属性.

commit阶段, workInProgress Fiber树 渲染到页面,FiberRootNode.current指向其,使其变成 current Fiber 树.

update时,

点击触发状态改变,这会 开启一次新的render阶段并构建一棵新的workInProgress Fiber 树

mount时 一样,render阶段,尝试复用,完成构建进入commit阶段完成渲染,current Fiber 树再次变更.

React技术揭秘–Fiber的工作原理

Fiber的工作原理(Fiber节点篇)

didReceiveUpdate = false 代表无法复用之前的Fiber,直接创建新Fiber替换

在mount时只有rootFiber会赋值Placement effectTag,在commit阶段只会执行一次插入操作,

换句话说,父节点无法复用,则所有子节点都会重新创建,不考虑复用。

React技术揭秘–架构篇Render阶段

JSX是什么

JSX 是一种语法糖,就像 async函数是Promise的语法糖.

  1. babel对JSX语法进行正则匹配,通过AST语法树,将JSX代码替换为了React.createElement()

  2. React.createElement() 运行时的返回值就是 虚拟DOM,也是 ReactElement

  3. 组件 mount 时, Reconciler 将 虚拟DOM 生成 Fiber节点

JSX => React.createElement() => 虚拟DOM => Fiber

React17开始将JSX库单独提出,以便其他库使用JSX语法,而可以不引入React, React.createElement() 变成了 jsx()

其他

回头再补:React18以前会EffectList(副作用链)收集副作用,React18.2没有effect了。现在从根节点递归收集副作用

18.2用 subTreeFlags,表示子节点是否有修改,冒泡

为什么Vue不需要Fiber

Diff算法

当key不同时只代表遍历到的该fiber不能被p复用,后面还有兄弟fiber还没有遍历到。所以仅仅标记该fiber删除


文章作者: 罗紫宇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗紫宇 !
  目录