【React源码】一帧中是否有空余时间

510 阅读1分钟

这篇应该属于Scheduler任务调度一章中,但是由于篇幅原因,单独拧出来

思路

我们已经知道,React源码是利用MessageChannel/setImmediate生成宏任务,在浏览器刷新的每一帧中见缝插针的执行React任务。

因为是参考requestIdleCallback实现的一帧内剩余时间能执行就执行,不能执行就暂停的原则。所以需要考虑实现下面几件事:

  • 1.如何确定一帧有多久
  • 2.当前帧对应的deadline
  • 3.判断是否需要让出执行权

一帧有多久(yieldInterval)

是通过变量yieldInterval确定。是定时器每次执行的时间间隔,也是浏览器一帧对应的时间。通过浏览器的fps来确定

  • 定义常量
let yieldInterval = 5;
  • 根据浏览器fps确定(forceFrameRate函数)
/**
    @params fps:当前浏览器每秒多少帧
*/
function forceFrameRate(fps) {
  if (fps > 0) {
    yieldInterval = Math.floor(1000 / fps);
  } else {
    yieldInterval = 5;
  }
}

当前帧什么时候结束(deadline)

确定了一帧时间长度以后,就需要确定在当前帧,什么时候结束,也就是结束的时候,要主动让出js执行权,交出cpu,防止阻塞

  • 定义常量
let deadline = 0;
  • 更新截止时间(performWorkUntilDeadline函数)
const performWorkUntilDeadline = () => {
    const currentTime = getCurrentTime();
    deadline = currentTime + yieldInterval;
};

当然performWorkUntilDeadline函数绝不止更新了deadline这一个功能,还会去主动执行当前任务(scheduleHostCallback常量/函数)

判断到时间了

既然截止时间也有了,只需要判断当前时间是否到截止时间了就好(shouldYieldToHost函数)

function shouldYieldToHost() {
    getCurrentTime() >= deadline
}

传送门

【欢迎探讨】