假设:rAF的now
时间是在所有回调被触发时计算的。因此,在该帧的第一个回调被调用之前发生的任何阻塞都不会影响rAF的now
,并且至少对于该第一个回调而言,它是准确的。
在触发rAF集之前进行的任何performance.now()测量都应早于rAF的now
。
测试:记录before
(在任何事情发生之前的基线时间)。设置下一个rAF。将rAF的now
和实际的performance.now()
与before
进行比较,以查看它们之间的差异。
预期结果:
var before = performance.now(), frames = ["with blocking", "with no blocking"], calls = 0;
requestAnimationFrame(function frame(rAFnow) {
var actual = performance.now();
console.log("frame " + (calls + 1) + " " + frames[calls] + ":");
console.log("before frame -> rAF now: " + (rAFnow - before));
console.log("before frame -> rAF actual: " + (actual - before));
if (++calls < frames.length) { before = actual; requestAnimationFrame(frame); }
});
// blocking
for (var i = 0, l = 0; i < 10000000; i++) {
l += i;
}
观察结果:当帧开始前存在阻塞时,rAF的now
时间有时会错误,甚至对于第一帧也是如此。有时第一帧的now
实际上比记录的before
时间还要早。
无论是否存在帧之前的阻塞,每隔一段时间,在帧内时间rAFnow
会比预先帧时间before
更早--即使我在进行第一次测量之后才设置rAF。尽管这很少见,但这种情况也可能发生,而没有任何阻塞。
(大多数情况下,第一个阻塞帧会出现时间错误。在其他情况下,也会偶尔遇到问题,如果您尝试运行几次,则会发生问题。)
通过更广泛的测试,我发现在回调之前阻塞的时间错误率为100帧中的1%,没有阻塞的时间错误率为约400帧中的0.21645021645021645%,似乎是由用户打开窗口或其他潜在的CPU密集型操作引起的。
因此,这种情况相当罕见,但问题是根本不应该发生。如果您想使用它们进行有用的操作,例如模拟时间、动画等,则需要这些时间来使其有意义。
我已经考虑了人们所说的话,但也许我仍然不明白事情的运作方式。如果这都是按规范的,我希望能得到一些伪代码以巩固我的理解。
更重要的是,如果有人有任何建议,可以让我避免这些问题,那就太棒了。唯一想到的办法是在每帧中测量自己的performance.now()
并使用该值--但这似乎有些浪费,因为它实际上在每帧中运行两次,另外还有任何触发的事件等。