React Fiber架构了解

产生的原因

React15 通过递归的方式进行渲染,使用的是 JS 引擎自身的函数调用栈,它会一直执行到栈空为止。这个过程 react 称为reconcilation(协调)。在reconcilation期间,react 会一直占用浏览器资源,会导致用户触发的事件得不到响应。

Fiber 实现了自己的组件调用栈,它以链表的形式遍历组件树,可以灵活的暂停、继续和丢弃执行的任务。实现方式是使用了浏览器 requestIdlecallback 这一AP1。

但是react开发了一个 requestIdlecallback

react实现: 框架内可以分为三层:

  • Virtual DOM层
  • Reconciler 层 生命周期调用 ,进行diff运算等
  • Renderer层 页面渲染

后续改动最大的 Reconciler 层,后续名称为 Fiber Reconciler,之前的 Reconciler 被命名为Stack Reconciler

Stack Reconciler的运行过程是不能被打断的,但是 Fiber Reconciler 每执行一端时间,就会将控制台交回浏览器,可以分段执行。这里的分段执行就需要 调度器Scheduling 来进行任务分配。

Fiber概念

react fiber是16版本之后的一种更新机制,使用链表取代了树,是一种fiber数据结构,其有三个指针,分别指向了父节点、子节点、兄弟节点,当中断的时候会记录下当前的节点,然后继续更新,它把组件渲染的工作分片,到时会主动让出渲染主线程。

Reconciliation (协调)

Reconciliation 是被普遍理解为"虚拟 DOM"的算法。当你渲染一个 React 应用程序时,一个描述应用程序的节点树被生成并保存在内存中。然后将该树刷新到渲染环境------ 例如,在浏览器应用程序的情况下,它被转换为一组 DOM 操作。当应用程序更新时(通常通过setState),会生成一棵新树。新树与之前的树进行比较,以计算更新渲染应用程序所需的操作。

Scheduling (调度)

确定什么时候应该执行某段代码。

调度核心理念便是:我们可以随心所欲的控制我们的代码。

Fiber做了很多切片任务,

详细调度可以看 React 的调度系统 Scheduler

Fiber Reconciler

Fiber Reconciler 运行会产生一个Fiber树,页面初始加载比较慢的原因是,也main渲染的同时,react内同时在生成Fiber树,加载较慢

运行的两个阶段:

  • 阶段一: render/ reconciliation
  • 阶段二:commit

阶段一:生成DOM树,得到需要更新的节点信息,这一步是渐进过程,可以被打断

阶段二:将需要更新的节点一次批量更新,这个过程不能被打断

Fiber 树

Fiber 是用链表结构遍历遍历组件树,并在页面初始加载阶段会创建Fiber树,

Fiber 是一个单链表树结构, 以 单链表 的数据结构, 以 后续遍历 的顺序,储存了 vdom树结构

Fiber结构

ini 复制代码
function FiberNode(tag, pendingProps, key, mode) {
  // Instance
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null;

  // 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.contextDependencies = null;

  this.mode = mode;

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

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

  this.expirationTime = NoWork;
  this.childExpirationTime = NoWork;

  this.alternate = null;

  if (enableProfilerTimer) {
    this.actualDuration = Number.NaN;
    this.actualStartTime = Number.NaN;
    this.selfBaseDuration = Number.NaN;
    this.treeBaseDuration = Number.NaN;

    this.actualDuration = 0;
    this.actualStartTime = -1;
    this.selfBaseDuration = 0;
    this.treeBaseDuration = 0;
  }

  // ...
}

每一个Fiber节点都是有子节点 child 、兄弟节点 sibling 和父节点 return等属性

例如下方代码:

javascript 复制代码
function App() {
  return (
    <div className="app">
      <span>hello</span>, Fiber
    </div>
  );
}

形成的Fiber树:

为什么vue不需要Fiber?

React16中使用了 Fiber,但是 Vue 是没有 Fiber 的,为什么呢?原因是二者的优化思路不一样:

  1. Vue 是基于 template 和 watcher 的组件级更新,把每个更新任务分割得足够小,不需要使用到 Fiber 架构,将任务进行更细粒度的拆分
  2. React 是不管在哪里调用 setState,都是从根节点开始更新的,更新任务还是很大,需要使用到 Fiber 将大任务分割为多个小任务,可以中断和恢复,不阻塞主进程执行高优先级的任务

其中弧线为调用顺序。紫色为 beginWork、粉色为 completeWork。beginWork 是 "递" 的过程,而 comleteWork 则是 "归" 的过程。

参考链接:

React Fiber

走进React Fiber的世界

Fiber原理

一篇带你了解 React Fiber 是什么?

react fiber概念及原理

这个没参考,留着后续看 理解react fiber原理

相关推荐
小满zs2 小时前
Zustand 第四章(中间件)
前端·react.js
GalaxyPokemon3 小时前
LeetCode - 2. 两数相加
java·前端·javascript·算法·leetcode·职场和发展
dualven_in_csdn5 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
你的人类朋友6 小时前
✍️【Node.js程序员】的数据库【索引优化】指南
前端·javascript·后端
小超爱编程7 小时前
纯前端做图片压缩
开发语言·前端·javascript
应巅7 小时前
echarts 数据大屏(无UI设计 极简洁版)
前端·ui·echarts
萌萌哒草头将军7 小时前
🚀🚀🚀什么?浏览器也能修改项目源文件了?Chrome 团队开源的超强 Vite 插件!🚀🚀🚀
vue.js·react.js·vite
Jimmy7 小时前
CSS 实现描边文字效果
前端·css·html
islandzzzz8 小时前
HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
Senar8 小时前
网页中如何判断用户是否处于闲置状态
前端·javascript