React源码分析(3)
首先在学习 scheduler 之前我们应当知道scheduler是什么,它实现了什么功能,
首先来讲scheduler的设计理念,具体的简化代码可以看笔者的另一篇文章
scheduler实现了什么?
------看了很多官方的解释,这里笔者不想那么死板了,用最简单的语言来快速理解吧
本质上就是通过scheduler来进行任务调度,为什么要任务调度,因为防止JS执行过程中阻碍了UI层的渲染。这就是核心~~~
OK,用最简单的话来说就是React在其内部的 UI = fn(state) 为了避免卡顿,提高渲染效率,采用封闭沙盒的形式,来进行视图的渲染,这里其实额外谈到了两个概念一个是上文中的 UI = fn(state) 公式以及这个地方其实聊到了浏览器的渲染机制,有兴趣的同学可以自己去额外了解一下。
其实简单地来说,对于JS而言,本质上的执行单线程永远不会改变,那么如何提高渲染的效率,不阻碍渲染?其实很简单,通过callback的方式,这里需要做一次通知,什么意思呢?就是说我们在浏览器进行绘制更新页面完成之后,我们回去找JS任务,在这个过程中,我们看一下距离下一次的绘制还有多少时间,够不够执行的,如果够,就执行,不够就等下,下一次再执行,在这方案基础上呢,其实目前有三种方式可以在渲染帧之后进行。
requestIdleCallback
requestAnimationFrame
MessageChannel
具体的三个方法的用法可以自行查阅MDN文档,这个地方我们只讲结果,最终的方案使用的是MessageChannel,为什么使用它而不是使用上文两个方法的原因很简单,requestIdleCallback的兼容性太差,这是浏览器最新的API提供事件循环空闲后处理,最高效的API但是兼容太差,requestAnimationFrame的问题在于,当页面隐藏状态下,方法回调会暂停,所以最后采用了消息通道MessageChannel。
OK,上文能够大概理解一下scheduler做了什么了,我们直接来看源码注释吧。
先分段贴出核心代码吧
消息通道的建立
最后执行的期限
请求消息通道状态
刷新工作流
核心工作流
调度入口
上面就是关于一个scheduler核心的一块代码展示了
具体的任务执行机制,笔者画了个图,可以参照对比
以上呢,就是基础的一套scheduler的源码解析和执行工作流程了,这里呢,作者并没有对lane模型,以及调度的原理模式进行深入讲解,原因是因为一方面网上这方面讲解很多,没有必要再复制一遍,二来,这篇文章其实在写了之后更多是想用最直白的方式来告诉读者,scheduler的执行,到底怎么回事,至于其他时间任务线的比对也好,执行优先级也好,就不在本篇文章中具体体现了。
最后简单总结一下吧!其实核心就是通过消息通道做个异步回调,然后根据执行帧做时间判定,然后有时间就执行,没时间就放一下,做个callbackcountainer存一下,下次来再先执行就OK啦,有兴趣的同学可以自己搭建一个模型,或者上文中的文章示例代码就OK啦!!
那么OK,Scheduler的源码分析到此结束啦!!!
最下面是全文注解,有兴趣的同学可以看看
如果喜欢作者的话,可以点击关注一下。
见山的Log