【React】React Fiber
React Fiber
自从 react 从15版更新到16版后,虽然使用上差别不会很大也提供了一定的兼容性,但是 react 的底层架构确有了很大的变化。React Fiber横空出世…
在了解 Fiber 之前,我们先了解几个概念,以及为什么需要引入 Fiber。
Reconciliation (协调)
Reconciliation 是 React 的协调算法的高级描述。
Reconciliation 是被普遍理解为“虚拟 DOM”的算法。当你渲染一个 React 应用程序时,一个描述应用程序的节点树被生成并保存在内存中。然后将该树刷新到渲染环境——例如,在浏览器应用程序的情况下,它被转换为一组 DOM 操作。当应用程序更新时(通常通过setState),会生成一棵新树。新树与之前的树进行比较,以计算更新渲染应用程序所需的操作。
Scheduling (调度)
可以理解为:确定什么时候应该执行某段代码。
调度核心理念便是:我们可以随心所欲的控制我们的代码。
React 目前没有很大程度的利用调度,所以才会引入Fiber。
Fiber
我们已经确定 Fiber 的主要目标是使 React 能够利用调度。
具体来说,我们需要能够:
- 暂停工作,稍后再回来。
- 为不同类型的工作分配优先级。
- 重用之前完成的工作。
- 如果不再需要,则中止工作。
为了做到这一点,我们首先需要一种将工作分解为单元的方法。从某种意义上说,这就是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)来做双缓存呢?
以下两点最为关键:
- fiber 是典型以空间换时间,提高运行效率;
- fiber 的出现是实现 function component 及 hook(state数据持久化)的关键;
参考文献:
- React Fiber 是什么
- 浅谈 React 里面的 Fiber
- react fiber 概念及原理
【React】React Fiber相关推荐
- 【构建】react打造你的第一个Bilibili首页开发项目
[构建]react打造你的第一个Bilibili首页开发项目 简 介 Hello 小极客们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富开源项目的动力![ ...
- 【入门】React 17 + Vite + ECharts 实现疫情数据可视化「02 快速搭建项目」
往期文章目录: [入门]React 17 + Vite + ECharts 实现疫情数据可视化「01 项目介绍篇」 文章目录 快速搭建项目 介绍 Vite Vite 特点 搭建第一个 Vite 项目 ...
- 【React】1077- React Fiber架构浅析
1.浏览器渲染 为了更好的理解 React Fiber, 我们先简单了解下渲染器进程的内部工作原理. 参考资料: 从内部了解现代浏览器(3)[1] 渲染树构建.布局及绘制[2] 1.1 渲染帧 帧 ( ...
- 【前端】react and redux教程学习实践,浅显易懂的实践学习方法。
前言 前几天,我在博文[前端]一步一步使用webpack+react+scss脚手架重构项目 中搭建了一个react开发环境.然而在实际的开发过程中,或者是在对源码的理解中,感受到react中用的最多 ...
- 【温故知新】—— React/Redux/React-router4基础知识独立团Demo
前言:React专注View层,一切皆组件:全部使用ES6语法,最新版本为React16. Redux是专注于状态管理的库,和react解耦:单一状态,单向数据流.[独立团github地址] 一.Re ...
- 【React】React 详细教程
前言 1.react与vue的对比 1.1.什么是模块化 是从代码的角度来进行分析的 把一些可复用的代码抽离为单独的模块:便于项目的维护和开发 1.2.什么是组件化 是从UI界面角度来进行分析的 把一 ...
- [置顶] 【稀饭】react native 实战系列教程之热更新原理分析与实现
很多人在技术选型的时候,会选择RN是因为它具有热更新,而且这是它的一个特性,所以实现起来会相对比较简单,不像原生那样,原生的热更新是一个大工程.那就目前来看,RN的热更新方案已有的,有微软的CodeP ...
- 【尚硅谷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. ...
- 【转】React Vue MVC MVVM MVP
首先,在谈这个话题之前, 我们有必要了解一下库和框架的区别. 我们先来看react官网以及vue官网对他们的定位: react: vue: react我们不说了,官网上明明白白说了,人家是一个libr ...
- 【React】React介绍环境搭建
一.React介绍 1.React是什么 一个专注于构建用户界面的 JavaScript 库,和vue和angular并称前端三大框架,不夸张的说,react引领了很多新思想,世界范围内是最流行的js ...
最新文章
- 腾讯张正友:计算机视觉的三生三世
- DC课程笔记-数字逻辑综合工具-DC Synthesis Optimization Techniques
- JavaSE各阶段练习题----集合-Collection-Set-List
- 一个C++程序执行main函数前和执行完main函数后会发生什么。
- html的实战性介绍
- float去掉小数点之后_float类型的存储方式
- php智能代码,php智能分页类代码原创
- 51单片机微波炉c语言程序,基于51单片机的微波炉控制C源程序.doc
- 算法入门—《啊哈算法》读书总结
- cnvd与cnnvd区别_漏洞都是怎么编号的CVE/CAN/BUGTRAQ/CNCVE/CNVD/CNNVD
- Hexo添加helper-live2d模型
- 2020的迷之骗局:从瑞幸退市到老干妈炒鹅 | 凌云时刻
- 吴涛作品介绍-易语言和VOLCANO 3D游戏引擎
- 计算机网络(2.12)物理层- 宽带接入技术-FTTx技术
- Image caption领域的研究现状及分析
- 计算机专业的梦想作文,我的梦想作文300字(通用15篇)
- Minecraft mod制作简易教程目录
- 上海市区广场、商场、大厦中英文对照大全
- Ae 中英文版本切换批处理文件
- matlab 游戏手柄,QtGamepad模块与游戏手柄交互小示例
热门文章
- 计算机网络故障提出问题,列控系统及其计算机网络的故障诊断与故障容错研究...
- Android 保存图片以后通知相册刷新
- chm 已取消到该网页的导航,打不开!
- 国家代码查询表(ISO 3166 Codes A2)
- ASA入门实验之NAT
- php更换banner图片,jQuery简单实现banner图片切换
- banner设圆角_com.youth.banner.Banner 使用glide加载圆角图片无效
- Python第三方库安装
- 在ubuntu 的QT中不能使用搜狗输入法
- 基于java的出租车预约网站