React系列- Scheduler 的原理
包含两个功能:
- 时间切片
- 优先级调度
时间切片
本质是模拟实现 requestIdleCallback
Scheduler 的时间切片功能是通过 task 宏任务实现的
常见的task 是 setTimeout ,但是有个 task 比 setTimeout 执行时机更加靠前,那就是 MessageChannel
所以 Scheduler 将需要被执行的回调函数作为 MessageChannel 的回调执行。
在 React的 render 阶段,开启并发模式时,每次遍历前,都会通过 Scheduler 提供的 shouldYield 方法判断是否需要中断遍历,使浏览器有时间渲染
是否中断的依据,最重要的一点便是每个任务的剩余时间是否用完.
优先级调度
不同的优先级 意味着不同时长的任务过期时间。
Scheduler 中存在两个队列:
- timerQueue: 保存未就绪任务
- taskQueue: 保存已就绪任务
每当有新的未就绪任务被注册,我们将其插入 timerQueue 并根据开始时间重新排列 timerQueue 中任务的顺序。
当 timerQueue中有任务就绪时,我们将其取出并加入 tashQueue 。
取出 taskQueue 中最早过期的任务并执行他。
为了能在 O(1) 复杂度中找到两个队列中时间最早的那个任务。Scheduler 使用 小顶堆 实现了 优先级队列
\