假设: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 < em>在之后,我进行了第一次测量。这也可以在没有任何阻塞的情况下发生,尽管这种情况很少见。
(我在大多数时间都会在第一个阻塞帧上出现时间错误。在其他阻塞帧上出现问题的情况比较少见,但如果尝试运行几次,偶尔会发生错误。)
通过更广泛的测试,我发现在回调之前阻塞的时间很短:100帧中的1%,没有阻塞:来自~400帧的0.21645021645021645%,似乎是由打开窗口或其他一些可能的CPU密集型操作引起的由用户。
所以这是相当罕见的,但问题是这根本不会发生。如果你想用它们做有用的事情,模拟时间,动画等,那么你需要那些时间才有意义。
我已经考虑过人们所说的话,但也许我仍然不理解事情的运作方式。如果这是所有的规格,我会喜欢一些伪代码来巩固它。
更重要的是,如果有人对如何解决这些问题有任何建议,那就太棒了。我唯一能想到的就是每帧都采用自己的performance.now()
测量并使用它 - 但它看起来有点浪费,每帧都有效地运行两次,除了任何触发事件之外等等。 / p>
答案 0 :(得分:7)
传递给requestAnimationFrame()
回调的时间戳是动画帧开始的时间。在同一帧期间调用的多个回调都接收相同的时间戳。因此,如果performance.now()
在参数值之前返回时间,那将会非常奇怪,但在之后 非常奇怪。
Here's the relevant specification:
当用户代理要为带有时间戳的的文档文档运行动画帧回调时,它必须运行以下步骤:
如果文档对象的hidden属性返回的值为true,则中止这些步骤。 [PAGE-VISIBILITY]
让回调成为文档动画帧回调列表中的条目列表,按照它们添加到列表中的顺序。
将文档的动画帧回调列表设置为空列表。
- 醇>
对于回调中的每个条目,按顺序:调用Web IDL回调函数,将 now 作为唯一参数传递,如果抛出异常,则报告异常。
所以你已经为下一个动画帧注册了一个回调(让我们只说一个)。勾选滴答滴答,BOOM,该动画帧的发生时间:
performance.now()
并将其与作为参数传入的 now 值进行比较。由于在步骤1和步骤6之间可能会经过短暂但不可忽略的时间,因此performance.now()
的返回值可能表示已经过了几微秒,甚至超过几微秒。 这是完全正常的行为。
答案 1 :(得分:2)
我在chrome上遇到了同样的问题,其中对performance.now ()
的调用返回的值高于now
window.requestAnimationFrame ()
值
我的解决方法是使用传递给第一个before
而非而不是now
的回调的window.requestAnimationFrame ()
设置performance.now ()
。似乎只使用两个函数中的一个来测量时间可以保证值的进展。
我希望这可以帮助其他任何因此而受苦的人。