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原理

相关推荐
放下华子我只抽RuiKe56 小时前
NLP自然语言处理硬核实战笔记
前端·人工智能·机器学习·自然语言处理·开源·集成学习·easyui
PieroPc6 小时前
电脑DIY组装报价系统 用MiMo V2 Pro 写html ,再用opencode(选MiMo 作模型) 当录入口
前端·html
工程师老罗6 小时前
lvgl有哪些布局?
前端·javascript·html
好家伙VCC6 小时前
# 发散创新:用Selenium实现自动化测试的智能断言与异常处理策略在现代Web应用开发中,*
java·前端·python·selenium
关中老四7 小时前
【原生JS甘特图MZGantt 】如何给父任务设置独立进度条
前端·javascript·甘特图
英俊潇洒美少年7 小时前
react 18 的fiber算法
前端·算法·react.js
xiegwei7 小时前
android Compose 图片星星评分组件
android·前端·elementui
小鹿软件办公7 小时前
Firefox 149 正式推送:多任务处理升级,五大新功能详解
前端·firefox
evering7 小时前
遍历备份 Chrome | Edge 浏览器插件目录
前端·chrome·crx
WiChP7 小时前
【V0.1B4】从零开始的2D游戏引擎开发之路
前端·javascript·游戏引擎