瞧一瞧React Fiber
啥是React Fiber?
React Fiber,简单来说就是一个从React v16开始引入的新协调引擎,用来实现Virtual DOM的增量渲染。
说人话:就是一种能让React视图更新过程变得更加流畅顺滑的处理手法。
我们都知道:进程大,线程小。而Fiber(纤维)是一种比线程还要细粒度的处理机制。从这个单词也可以猜测:React Fiber会很“细”。到底怎么个细法,我们接着往下看。
为什么会有React Fiber?
之前说了,React Fiber是为了让React的视图更新过程变得更加流畅顺滑。怎么,之前React的视图更新不流畅,不顺滑了?
还真是的,在React v16之前,React的视图更新确实存在很大的性能问题,其中首当其冲的,就是它的同步更新机制。
在React决定要加载或更新一颗组件树之前,会大致做出如下一系列动作:调用各组件的生命周期函数 --> 计算和对比Virtual DOM --> 更新真实的DOM树。这个过程是同步的,也就是说,一旦这个过程开始,它就会一鼓作气跑完,一直到真实DOM树更新完毕。
然而,当组件树比较庞大时,这种机制的问题就来了:一颗拥有300个组件的组件树需要全部更新,假设一个组件更新只需耗时1ms,整棵树更新一次就需要耗时300ms。在这300ms期间,浏览器的主线程一直在“专心致志”地忙着更新这颗组件树(这时函数的调用栈会非常长),对于页面上的任何操作都是“不闻不问”的。在这期间,假如用户在一个输入框敲了几个字,页面上也不会有任何反应,因为渲染按键输入结果也需要主线程来做,然而此时主线程正忙着更新组件树呢。等到300ms结束了,浏览器主线程有空了,才把刚刚敲的那几个字渲染到input输入框内。
太卡了,真的。
由于JavaScript的单线程工作特点,业内一直有个这样的原则:**任何动作都不要长时间霸占主线程,如果迟迟不归还主线程,那么在这期间程序就没法对其他输入作出响应。**输入了却没有响应,或者说响应来的很慢,也就是我们常常说的“卡顿”。显然,React的同步更新机制在组件树庞大时就违反了这一原则,犯了大忌。
这就是React Fiber出现的原因:为了解决旧版React视图更新的性能瓶颈。
React Fiber到底怎么工作的?
首先,React Fiber并没有解决更新庞大组件树耗时长的问题,实际上总的耗时还是一样的长。但是它解决了一个被广大开发者口诛笔伐的恶行:长时间霸占主线程不放。
而它解决的方法就是:分片。
它的工作原理是这样的:把耗时长的更新任务拆解成一个个小的任务分片,每执行完一个小的任务分片,都归还一次主线程,看看有没有什么其他紧急任务要做。如果在归还主线程时恰巧发现有紧急任务,那么会马上停掉当前更新任务,转而让主线程去做紧急任务,等主线程做完紧急任务,再重新做更新任务。(注意️:是重新!不是从上次被打断的点继续);如果没有紧急任务,才敢唯唯诺诺地继续做接下来的任务分片。
简单来说,就是降了视图更新的优先级,把更新过程碎片化。
现在我们捋一捋,React Fiber会这样处理一个更新过程:
- 将一个更新过程分为Reconciliation阶段和Commit阶段;
- 对于Reconciliation阶段进行分片处理,这个阶段可以被更紧急的任务打断,分片任务做到一半可能要重来;
- 对于Commit阶段,直接一鼓作气把DOM更新完,不能被打断。
React Fiber对我们日常开发有什么影响?
React Fiber在Reconciliation阶段可能会调用以下生命周期函数(这也意味着在这个阶段的生命周期函数在一次加载和更新过程中可能会被多次调用):
componentWillMountcomponentWillUpdatecomponentWillReceivePropsshouldComponentUpdate
如果你恰巧没有上react hooks的车,而是使用传统的类组件进行开发,那么切记,不要在以上几个生命周期函数中做只需要做一次的操作(比如:页面初始化时发起一个ajax请求获取数据)。
如果你平常使用react hooks进行开发,那没事了,就当看了个热闹。
瞧一瞧React Fiber的更多相关文章
- 瞧一瞧,看一看呐,用MVC+EF快速弄出一个CRUD,一行代码都不用写,真的一行代码都不用写!!!!
瞧一瞧,看一看呐用MVC+EF快速弄出一个CRUD,一行代码都不用写,真的一行代码都不用写!!!! 现在要写的呢就是,用MVC和EF弄出一个CRUD四个页面和一个列表页面的一个快速DEMO,当然是在不 ...
- Omi架构与React Fiber
原文链接-https://github.com/AlloyTeam/omi/tree/master/tutorial 写在前面 Omi框架在架构设计的时候就决定把update的控制权交给了开发者,视灵 ...
- React Fiber源码分析 (介绍)
写了分析源码的文章后, 总觉得缺少了什么, 在这里补一个整体的总结,输出个人的理解~ 文章的系列标题为Fiber源码分析, 那么什么是Fiber,官方给出的解释是: React Fiber是对核心算法 ...
- react fiber
react fiber https://github.com/acdlite/react-fiber-architecture https://github.com/facebook/react/is ...
- React Fiber 数据结构揭秘
此章节会通过两个 demo 来展示 Stack Reconciler 以及 Fiber Reconciler 的数据结构. 个人博客 首先用代码表示上图节点间的关系.比如 a1 节点下有 b1.b2. ...
- React Fiber源码分析 第二篇(同步模式)
先附上两张流程图 1.scheduleRootUpdate 这个函数主要执行了两个操作 1个是创建更新createUpdate并放到更新队列enqueueUpdate, 1个是执行sheculeW ...
- React Fiber源码分析 第一篇
先附上流程图一张 先由babel编译, 调用reactDOM.render,入参为element, container, callback, 打印出来可以看到element,container,cal ...
- React Fiber源码分析 第三篇(异步状态)
先附上流程图~ 调用setState时, 会调用classComponentUpdater的enqueueSetState方法, 同时将新的state作为payload参数传进 enqueueSetS ...
- 2020最新的web前端体系和路线图,想学web前端又不知道从哪开始的快来瞧一瞧呀
web前端其实是相对于服务器语言是简单的,并且对于初学者是非常友好的,因为在前期学习能够看到很好的效果.但是他的路线 也就是学习体系不成熟,所以导致很多初学者不知道怎么学?下面我就讲讲web前端的体系 ...
随机推荐
- 十:SpringBoot-配置AOP切面编程,解决日志记录业务
SpringBoot-配置AOP切面编程,解决日志记录业务 1.AOP切面编程 1.1 AOP编程特点 1.2 AOP中术语和图解 2.SpringBoot整合AOP 2.1 核心依赖 2.2 编写日 ...
- java--Aop--记录日志
package com.pt.modules.log; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; imp ...
- OpenStack (haproxy)
openstack部署脚本 链接:<https://pan.baidu.com/s/1BTp_tGNC6ZWwVmKkhwivgw > 提取码:jxuz haproxy 官网:< h ...
- mysql:如何利用覆盖索引避免回表优化查询
说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml 17 ...
- Python 字符串指定位置替换字符
指定位置替换字符 def replace_char(old_string, char, index): ''' 字符串按索引位置替换字符 ''' old_string = str(old_string ...
- 负载均衡之LVS与Nginx对比
今天总结一下负载均衡中LVS与Nginx的区别,好几篇博文一开始就说LVS是单向的,Nginx是双向的,我个人认为这是不准确的,LVS三种模式中,虽然DR模式以及TUN模式只有请求的报文经过Direc ...
- Hive创建HBase,ES外部表
1.创建HBase外部表 CREATE EXTERNAL TABLE `ods_women`( `rowkey` string COMMENT 'from deserializer', `articl ...
- Java_web项目中在Java文件里面通过类装载器对资源文件读取
承接上一节:在eclipse完成对Java_web项目里面资源文件的读取 我们首先在src目录下创建一个资源文件db.properties 内容如下: url=127.0.0.1 name=root ...
- Codeforces Round #683 (Div. 2, by Meet IT) D. Catching Cheaters (DP)
题意:给你两个字符串,每次取它们的子串C和D,然后求LCS,得到的贡献为\(4*LCS(C,D)-|C|-|D|\),求最大贡献. 题解:首先应该了解\(O(n^2)\)的LCS的dp写法,然后在此基 ...
- .net中swagger忽略某些字段
需要忽略的字段上用特性 [System.Text.Json.Serialization.JsonIgnore] 例如: