欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

精读React核心概念(1) --React Fiber

程序员文章站 2022-07-03 08:43:13
...

前言

最近为了深化自己React核心概念的学习,在掘金上认真学习荒山大佬的文章,个人感觉主要有两部分,一部分是每年的React Conf推出的新的核心特性的深入理解,一种是React的开发规范和设计原则。个人学习过程中感觉到受益匪浅,因此在这里根据自己的学习总结一下,肯定没有荒山讲得好,大家可以通过这个链接去看荒山大佬的文章,当然如果你想简单的了解一下的话,我的文章会更简单点.

单处理进程调度

在讲Fiber之前,为了更好的理解,先讲一下单处理进程的几个调度方法。

首先是先到先得的方法,也可以认为没有方法,谁先来处理谁,这样做的坏处显而易见,对于一些短时间进程,他们前面如果有很长时间的进程在处理,就会很耽误他们自己的处理时间,因为如果先处理他们的话会很快的处理完;同时也对IO密集型任务不利,他们阻塞休眠后又会重新回到候选队列。

接着是时钟轮转的调度方法,设定一个时间段,每过这个时间段或者阻塞休眠时就会先放下,去处理其他的进程。这样做法有个问题就是时间段的大小不好确定,设定长了其实和
第一种方法没什么区别,太短的话,线程切换也是耗时的,自然也不好;同时这样的方法也没有解决IO密集型任务的问题。

接着是最短进程优先的方法,顾名思义,这种方法的话属于非抢占型策略,这样操作的缺点也是显而易见,对长进程不利;同时如果长进程进行处理,后面的短进程还是同第一种方法一样迟迟得不到响应。

针对上一种方法的缺点,还有最短剩余时间的方法,新的进程进来后,如果它的执行时间短于正在执行的老进程,那么就会先处理较短的,这样的方式仍然没有解决长进程饥饿的缺陷。

最高响应比优先,主要是针对上面无法处理长进程饥饿的问题提出的,它提供了一个公式来计算相应比:

响应比 = (等待执行时间 + 进程执行时间) / 进程执行时间

这样一定程度上解决了长进程饥饿的问题。

注意上面关于基于最短进程优先的三种方法,它们都是要计算进程处理时间的,这当然也要消耗一部分资源,因此我们提出了一种反馈法,使得他们开始都有同样的优先度,使用抢占策略(诸如时钟轮转)后,他们的优先度就会降低。具体可以唱看荒山大佬的文章,我觉得讲到这里就差不多了。

为什么讲这个

简单地说,JS是单线程的:

它要负责页面的JS解析和执行、绘制、事件处理、静态资源加载和处理, 这些任务可以类比上面’进程‘

相似的,如果有一个“长进程”任务长期霸占CPU,我们也要使用某种调度方法,让用户的体验更加完美,即使扔是只有一个进程在处理,但是给用户的体验是不一样的,就如同我们计算机的进程调度方式一样。

那么Fiber是什么

简单地说,Fiber可以让这种类似CPU密集型的长进程任务变为可中断的任务,通过进程调度可以让浏览器更及时的响应用户的操作。

React 渲染的过程可以被中断,可以将控制权交回浏览器,让位给高优先级的任务,浏览器空闲后再恢复渲染

具体来说,浏览器中其实并没有抢占机制,其实也不存在类似进程的概念,实则是使用了类似协程的控制权让出机制,专业点讲这叫合作式调度,这里浏览器掌握着控制大权,用图表可以如下表示:
精读React核心概念(1) --React Fiber
那么什么时候浏览器才能判断应该让出控制权了呢,或者说它怎么判断应该处理高优先度任务了呢?

其实他没有办法判断哪些是所谓的高优先级任务,但是它利用了类似requestIdleCallback原理的方法去解决这个问题,通俗的讲,为了优化用户使用浏览器的体验,他会让浏览器在保证运行流畅的前提下,一有空就去回调处理其他事务,同时为了避免任务被饿死,react也做了设置超时时间的设定,使得应该被进行的任务都能被完成。

但是requestIdleCallback这个API目前只有Chrome支持了,所以React自己实现了一个。

同时,尽管这个功能和ES6中generater很像,React也没有直接用,而是使用了Fiber这种方式来替代,具体实现步骤这个荒山大佬的图讲的很清楚:
精读React核心概念(1) --React Fiber
具体Fiber的实现这里就不讲了,有兴趣可以看原文,同时Fiber是一项非常庞大的任务,可能我们要做的并没有什么,但是潜在里我们程序做的东西已经沧海桑田。