说说对Fiber架构的理解?解决了什么问题?

简介: 说说对Fiber架构的理解?解决了什么问题?

前言


JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行时,另一个线程只能挂起等待


如果 JavaScript 线程长时间地占用了主线程,那么渲染层面的更新就不得不长时间地等待,界面长时间不更新,会导致页面响应度变差,用户可能会感觉到卡顿


而这也正是 React 15 的 Stack Reconciler所面临的问题,当 React在渲染组件时,从开始到渲染完成整个过程是一气呵成的,无法中断


如果组件较大,那么js线程会一直执行,然后等到整棵VDOM树计算完成后,才会交给渲染的线程


这就会导致一些用户交互、动画等任务无法立即得到处理,导致卡顿的情况。


一、React Fiber是什么?


React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现。从Facebook在 React Conf 2017 会议上确认,React Fiber 在React 16 版本发布


在react中,主要做了以下的操作:


为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务。

增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行。

dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行。

从架构角度来看,Fiber 是对 React核心算法(即调和过程)的重写。


从编码角度来看,Fiber是 React内部所定义的一种数据结构,它是 Fiber树结构的节点单位,也就是 React 16 新架构下的虚拟DOM。


一个fiber就是一个 JavaScript对象,包含了元素的信息、该元素的更新操作队列、类型,其数据结构如下:


type Fiber = {
  // 用于标记fiber的WorkTag类型,主要表示当前fiber代表的组件类型如FunctionComponent、ClassComponent等
  tag: WorkTag,
  // ReactElement里面的key
  key: null | string,
  // ReactElement.type,调用`createElement`的第一个参数
  elementType: any,
  // The resolved function/class/ associated with this fiber.
  // 表示当前代表的节点类型
  type: any,
  // 表示当前FiberNode对应的element组件实例
  stateNode: any,
  // 指向他在Fiber节点树中的`parent`,用来在处理完这个节点之后向上返回
  return: Fiber | null,
  // 指向自己的第一个子节点
  child: Fiber | null,
  // 指向自己的兄弟结构,兄弟节点的return指向同一个父节点
  sibling: Fiber | null,
  index: number,
  ref: null | (((handle: mixed) => void) & { _stringRef: ?string }) | RefObject,
  // 当前处理过程中的组件props对象
  pendingProps: any,
  // 上一次渲染完成之后的props
  memoizedProps: any,
  // 该Fiber对应的组件产生的Update会存放在这个队列里面
  updateQueue: UpdateQueue<any> | null,
  // 上一次渲染的时候的state
  memoizedState: any,
  // 一个列表,存放这个Fiber依赖的context
  firstContextDependency: ContextDependency<mixed> | null,
  mode: TypeOfMode,
  // Effect
  // 用来记录Side Effect
  effectTag: SideEffectTag,
  // 单链表用来快速查找下一个side effect
  nextEffect: Fiber | null,
  // 子树中第一个side effect
  firstEffect: Fiber | null,
  // 子树中最后一个side effect
  lastEffect: Fiber | null,
  // 代表任务在未来的哪个时间点应该被完成,之后版本改名为 lanes
  expirationTime: ExpirationTime,
  // 快速确定子树中是否有不在等待的变化
  childExpirationTime: ExpirationTime,
  // fiber的版本池,即记录fiber更新过程,便于恢复
  alternate: Fiber | null,
}


二、解决的问题


1、掉帧


在react 15以及之前,还没有fiber的概念,

当虚拟dom量非常大非常复杂时,react在递归进行渲染时会非常耗时,会一直递归进行,会造成页面卡顿掉帧的现象,严重情况下浏览器还可能失去响应。


fiber有协调与提交两个阶段,协调包含了fiber创建与diff更新,此过程可暂停。而提交必须同步执行,保证渲染不卡顿。


2、并发


fiber实现了并发,为任务赋予不同优先级,保证了一有时间总是做最高优先级的事,而不是先来先占位死板的去执行。


总结


fiber它就是一种数据结构,包含了任务开始时间,节点关系信息(return,child这些),我们把视角往上抬一点,我们也可以说fiber是一种模拟调用栈的特殊链表,目的是为了解决传统调用栈无法暂停的问题。


而站在宏观角度fiber又是一种调度让出机制,它让react达到了增量渲染的目的,在保证帧数流畅的同时,fiber总是在浏览器有剩余时间的情况下去完成目前目前最高优先级的任务。


目录
相关文章
|
9月前
|
前端开发 JavaScript 算法
说说对Fiber架构的理解?解决了什么问题?
说说对Fiber架构的理解?解决了什么问题?
44 0
|
5月前
|
移动开发 前端开发 JavaScript
react fiber架构【详细讲解,看这一篇就够了】
react fiber架构【详细讲解,看这一篇就够了】
183 0
|
9月前
|
前端开发 JavaScript 算法
【说说你对fiber架构的理解?解决了什么问题?】
【说说你对fiber架构的理解?解决了什么问题?】
|
9月前
|
前端开发 JavaScript 算法
对Fiber架构的理解?解决了什么问题?
对Fiber架构的理解?解决了什么问题?
71 0
|
9月前
|
前端开发 JavaScript 算法
说说你对fiber架构的理解?解决了什么问题?
说说你对fiber架构的理解?解决了什么问题?
|
10月前
|
缓存 JavaScript 前端开发
理解React中Fiber架构(二)
自从React16版本更新了Hook用法,同时引入了新的Fiber架构去重构整个渲染和事件处理过程,React团队引入Hook是为了更好剥离业务代码,让开发能更加友好的抽象代码,达到低耦合的函数组件目的,那么重构Diff算法,引入Fiber架构是为了什么呢? 其实只是为了能够一个目标快速响应,原先Diff算法时间复杂度为O(n3) O(n^3)O(n3) ,最后经过Fiber重构达到了O(n)O(n)O(n),这里面具体有什么门道,值得我们去深入研究一下。
367 0
|
10月前
|
Web App开发 XML 缓存
理解React中Fiber架构(一)
自从React16版本更新了Hook用法,同时引入了新的Fiber架构去重构整个渲染和事件处理过程,React团队引入Hook是为了更好剥离业务代码,让开发能更加友好的抽象代码,达到低耦合的函数组件目的,那么重构Diff算法,引入Fiber架构是为了什么呢? 其实只是为了能够一个目标快速响应,原先Diff算法时间复杂度为O(n3) O(n^3)O(n3) ,最后经过Fiber重构达到了O(n)O(n)O(n),这里面具体有什么门道,值得我们去深入研究一下。
198 0
|
前端开发
React Fiber生命周期及架构
React Fiber生命周期及架构
|
前端开发 JavaScript 算法
Deep In React之浅谈 React Fiber 架构(一)
2016 年都已经透露出来的概念,这都 9102 年了,我才开始写 Fiber 的文章,表示惭愧呀。不过现在好的是关于 Fiber 的资料已经很丰富了,在写文章的时候参考资料比较多,比较容易深刻的理解。
160 0
Deep In React之浅谈 React Fiber 架构(一)
|
存储 前端开发 算法
React系列——React Fiber 架构介绍资料汇总(翻译+中文资料)
React系列——React Fiber 架构介绍资料汇总(翻译+中文资料)
232 0