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

相关推荐
命运之光3 分钟前
生日主题的烟花特效HTML,CSS,JS
前端·javascript·css
Cshaosun28 分钟前
js版本之ES5特性简述【String、Function、JSON、其他】(二)
前端·javascript·es
__WanG31 分钟前
Flutter将应用打包发布到App Store
前端·flutter·ios
leluckys34 分钟前
flutter 专题十七 Flutter Flar动画实战
前端·flutter
豆包MarsCode1 小时前
我用豆包MarsCode IDE 做了一个 CSS 权重小组件
开发语言·前端·javascript·css·ide·html
22x艾克斯1 小时前
Web Notifications API-让网页也能像QQ一样实现消息通知
前端
想你的风吹到了瑞士1 小时前
变量提升&函数提升
前端·javascript·vue.js
生椰拿铁You1 小时前
12 —— Webpack中向前端注入环境变量
前端
Huazzi.2 小时前
免费好用的静态网页托管平台全面对比介绍
前端·网络·github·web
吃土少女古拉拉2 小时前
前端和后端
前端·学习笔记