React Fiber

自从 react 从15版更新到16版后,虽然使用上差别不会很大也提供了一定的兼容性,但是 react 的底层架构确有了很大的变化。React Fiber横空出世…

在了解 Fiber 之前,我们先了解几个概念,以及为什么需要引入 Fiber。

Reconciliation (协调)

Reconciliation 是 React 的协调算法的高级描述。

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

Scheduling (调度)

可以理解为:确定什么时候应该执行某段代码。

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

React 目前没有很大程度的利用调度,所以才会引入Fiber。

Fiber

我们已经确定 Fiber 的主要目标是使 React 能够利用调度。

具体来说,我们需要能够:

  1. 暂停工作,稍后再回来。
  2. 为不同类型的工作分配优先级。
  3. 重用之前完成的工作。
  4. 如果不再需要,则中止工作。

为了做到这一点,我们首先需要一种将工作分解为单元的方法。从某种意义上说,这就是Fiber。

一个 Fiber 代表一个工作单元。


React15 最大的问题就是 Reconciler(协调)阶段产生产生虚拟DOM是通过深度优先递归的,并且中途不可间断。所以假如虚拟DOM很深的话,由于 JS 线程和浏览器 GUI 线程是互斥的,处理 js 的时间过长,会导致浏览器刷新的时候掉帧,造成卡顿。而 React16 则实现了异步的可中断的更新。

那么 Fiber 到底是个啥?其实 Fiber 怎么说都可以…Fiber可以理解为一种架构,Fiber也可以理解为一种数据结构,也可以是常说的最小的工作单元。

常说的 Fiber 树就是将 Fiber 当作一种架构来看待的,Fiber怎么连接成树呢?三个关键的属性:

// 指向父级Fiber节点
this.return = null;
// 指向子Fiber节点
this.child = null;
// 指向右边第一个兄弟Fiber节点
this.sibling = null;

所以在 react16 里面,一个组件对应的就是一棵 Fiber 树。那更新的时候,Fiber 这棵树有什么作用呢?react16 里面有一个很有意思的技术解答了——“双缓存技术”。

双缓存简单来说就是,在 React 里面最多同时存在两棵 Fiber 树,都在内存中构建,构建完成后直接替换。在源码里面,当前屏幕上显示内容对应的 Fiber 树称为 current fiber 树,正在内存中构建的 Fiber 树称为 workInProgress fiber 树。两棵树之间通过 alternate 属性连接。

currentFiber.alternate === workInProgressFiber;
workInProgressFiber.alternate === currentFiber;


上图中,rootFiber 是 react 应用,footFiberNode 是应用挂在的节点,current 指向的 fiber 是渲染在页面中的 fiber (即出现在屏幕中的视图),我们称它为 current fiber, current fiber 的每一个 fiber 节点都有一个 alternode 指向另一个棵树的相同 fiber 节点,我们称这个 fiber 为 workInProgress fiber。
  我们知道,当 react v16 前的版本更新时,会进行 jsx 和虚拟 dom 树进行 diff 算法,计算结果就是最终需要更新的视图。而在 react v16 diff 算法是将 jsx 和 workInProgress fiber 进行计算,最终得出最终视图,然后将 current 指针指向 workInProgress fiber,渲染新的视图。跟 workInProgress fiber 进行 diff 算法是在内存中进行的,即使被中断也对现有视图不产生影响。

那么 Fiber 和 React 里面重要的一个概念 JSX 有什么区别和联系呢?

简单来说,JSX 就是 html+js,由于和 UI 的本质形式很相似,所以这理解起来也很轻松。而通过 JSX 创建的组件就是 React15 里面的虚拟 DOM,实质上虚拟 DOM 是由 React.createElement 这个函数创建的。其中就要用到 babel 转译器了。

Babel 转译 JSX 的过程简要:

Babel 通过 parse() 函数将 JSX 解析成 AST 抽象语法树,一种树状的形式表现编程语言的语法结构。

依据解析的 AST,再通过 Babel 的 transform() 函数生成 React.createElement() 代码
再来看 React.createElement() 创建返回的 JSX 数据结构。

  return ReactElement(type,key,ref,self,source,ReactCurrentOwner.current,props,);
}

所以,由此可以看见,一个组件的JSX和Fiber节点的数据结构不同。组件在 mount 时,根据 JSX 来创建对应的 Fiber 节点。

扩展

通过上文我们知道了,react 是通过双缓存技术来实现可中断的更新,那么为什么不用原本的架构(虚拟 dom)来做双缓存呢?

以下两点最为关键:

  1. fiber 是典型以空间换时间,提高运行效率;
  2. fiber 的出现是实现 function component 及 hook(state数据持久化)的关键;

参考文献:

  1. React Fiber 是什么
  2. 浅谈 React 里面的 Fiber
  3. react fiber 概念及原理

【React】React Fiber相关推荐

  1. 【构建】react打造你的第一个Bilibili首页开发项目

    [构建]react打造你的第一个Bilibili首页开发项目 简 介 Hello 小极客们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富开源项目的动力![ ...

  2. 【入门】React 17 + Vite + ECharts 实现疫情数据可视化「02 快速搭建项目」

    往期文章目录: [入门]React 17 + Vite + ECharts 实现疫情数据可视化「01 项目介绍篇」 文章目录 快速搭建项目 介绍 Vite Vite 特点 搭建第一个 Vite 项目 ...

  3. 【React】1077- React Fiber架构浅析

    1.浏览器渲染 为了更好的理解 React Fiber, 我们先简单了解下渲染器进程的内部工作原理. 参考资料: 从内部了解现代浏览器(3)[1] 渲染树构建.布局及绘制[2] 1.1 渲染帧 帧 ( ...

  4. 【前端】react and redux教程学习实践,浅显易懂的实践学习方法。

    前言 前几天,我在博文[前端]一步一步使用webpack+react+scss脚手架重构项目 中搭建了一个react开发环境.然而在实际的开发过程中,或者是在对源码的理解中,感受到react中用的最多 ...

  5. 【温故知新】—— React/Redux/React-router4基础知识独立团Demo

    前言:React专注View层,一切皆组件:全部使用ES6语法,最新版本为React16. Redux是专注于状态管理的库,和react解耦:单一状态,单向数据流.[独立团github地址] 一.Re ...

  6. 【React】React 详细教程

    前言 1.react与vue的对比 1.1.什么是模块化 是从代码的角度来进行分析的 把一些可复用的代码抽离为单独的模块:便于项目的维护和开发 1.2.什么是组件化 是从UI界面角度来进行分析的 把一 ...

  7. [置顶] 【稀饭】react native 实战系列教程之热更新原理分析与实现

    很多人在技术选型的时候,会选择RN是因为它具有热更新,而且这是它的一个特性,所以实现起来会相对比较简单,不像原生那样,原生的热更新是一个大工程.那就目前来看,RN的热更新方案已有的,有微软的CodeP ...

  8. 【尚硅谷React】——React全家桶笔记

    文章目录 第1章 React简介 1.1 React的特点 1.2 引入文件 1.3 JSX 1.3.1 为什么要用JSX 1.3.2 JSX语法规则 1.4 虚拟DOM 1.5 模块与组件 1.5. ...

  9. 【转】React Vue MVC MVVM MVP

    首先,在谈这个话题之前, 我们有必要了解一下库和框架的区别. 我们先来看react官网以及vue官网对他们的定位: react: vue: react我们不说了,官网上明明白白说了,人家是一个libr ...

  10. 【React】React介绍环境搭建

    一.React介绍 1.React是什么 一个专注于构建用户界面的 JavaScript 库,和vue和angular并称前端三大框架,不夸张的说,react引领了很多新思想,世界范围内是最流行的js ...

最新文章

  1. 腾讯张正友:计算机视觉的三生三世
  2. DC课程笔记-数字逻辑综合工具-DC Synthesis Optimization Techniques
  3. JavaSE各阶段练习题----集合-Collection-Set-List
  4. 一个C++程序执行main函数前和执行完main函数后会发生什么。
  5. html的实战性介绍
  6. float去掉小数点之后_float类型的存储方式
  7. php智能代码,php智能分页类代码原创
  8. 51单片机微波炉c语言程序,基于51单片机的微波炉控制C源程序.doc
  9. 算法入门—《啊哈算法》读书总结
  10. cnvd与cnnvd区别_漏洞都是怎么编号的CVE/CAN/BUGTRAQ/CNCVE/CNVD/CNNVD
  11. Hexo添加helper-live2d模型
  12. 2020的迷之骗局:从瑞幸退市到老干妈炒鹅 | 凌云时刻
  13. 吴涛作品介绍-易语言和VOLCANO 3D游戏引擎
  14. 计算机网络(2.12)物理层- 宽带接入技术-FTTx技术
  15. Image caption领域的研究现状及分析
  16. 计算机专业的梦想作文,我的梦想作文300字(通用15篇)
  17. Minecraft mod制作简易教程目录
  18. 上海市区广场、商场、大厦中英文对照大全
  19. Ae 中英文版本切换批处理文件
  20. matlab 游戏手柄,QtGamepad模块与游戏手柄交互小示例

热门文章

  1. 计算机网络故障提出问题,列控系统及其计算机网络的故障诊断与故障容错研究...
  2. Android 保存图片以后通知相册刷新
  3. chm 已取消到该网页的导航,打不开!
  4. 国家代码查询表(ISO 3166 Codes A2)
  5. ASA入门实验之NAT
  6. php更换banner图片,jQuery简单实现banner图片切换
  7. banner设圆角_com.youth.banner.Banner 使用glide加载圆角图片无效
  8. Python第三方库安装
  9. 在ubuntu 的QT中不能使用搜狗输入法
  10. 基于java的出租车预约网站