优化背景:
在react16 版本之前,react 的更新渲染存在着一些性能的问题,这个问题产生的原因是因为在更新/渲染时,采用递归的方式(栈调度器),而递归有一个不好的地方就是,他不能被随意的break;也不能在break之后也很难恢复到break之前的状态,而因为浏览器是单线程的,V8 引擎执行js 和 渲染引擎渲染页面是两个互斥的行为,这也就是说当更新任务太庞大的时候,js执行太久而致使页面丢帧,不流畅,甚至卡顿。
优化方式
react16 之后,react团队在react中加入了一个全新的架构:Fiber,并赋予了他光荣而艰巨的使命----解决16版本之前的性能问题;
Fiber 架构实际上是个链表结构,每个节点包含了 return,subling,children。他们分别代表父节点,兄弟节点,子节点。有了链表结构,那就可以进行DFS,而且也可以很轻松的break & continue;
当然,上述都是题外话,今天主要分析react 中的 scheduler。
今天的正题:scheduler
个人拙见,如有问题希望大佬指正。知也无涯,共勉!
今天主要分析的源码的就是,react 中的任务调度器。在16.8版本之后,scheduler已经被react 团队从react-dom中抽离了出来,作为一个独立的包单独发布到npm上。
if (expirationTime === Sync) {
callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
} else {
callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root),
{
timeout: expirationTimeToMs(expirationTime) - now()
});
}
这段代码位于react-dom 的源码中,说明了,其中的expirationTime代表了过期时间,当为Sync的时候继续沿用react16版本之前的更新,否则就会采用全新的调度规则。
而其中的performConcurrentWorkOnRoot 就是一个即将执行的任务,它被传入scheduler中,进行调度处理。
unstable_scheduleCallback
这是schedule中抛出的一个核心方法,该方法主要执行了以下几个操作
1: 声明一个信的Task对象属性如下
var newTask = {
id: taskIdCounter+