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

相关推荐
gnip4 小时前
企业级配置式表单组件封装
前端·javascript·vue.js
一只叫煤球的猫5 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
excel6 小时前
Three.js 材质(Material)详解 —— 区别、原理、场景与示例
前端
掘金安东尼6 小时前
抛弃自定义模态框:原生Dialog的实力
前端·javascript·github
hj5914_前端新手10 小时前
javascript基础- 函数中 this 指向、call、apply、bind
前端·javascript
薛定谔的算法10 小时前
低代码编辑器项目设计与实现:以JSON为核心的数据驱动架构
前端·react.js·前端框架
Hilaku10 小时前
都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?
前端·javascript·css
yangcode10 小时前
iOS 苹果内购 Storekit 2
前端
LuckySusu10 小时前
【js篇】JavaScript 原型修改 vs 重写:深入理解 constructor的指向问题
前端·javascript
LuckySusu10 小时前
【js篇】如何准确获取对象自身的属性?hasOwnProperty深度解析
前端·javascript