【发布时间】:2016-07-13 19:34:26
【问题描述】:
假设: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 after 我进行了第一次测量。这也可以在没有任何阻塞的情况下发生,尽管这种情况很少见。
(我大部分时间在第一个阻塞帧上出现计时错误。在其他帧上出现问题的情况很少见,但如果您尝试运行几次,偶尔会发生。)
通过更广泛的测试,我发现回调之前阻塞的糟糕时间:100 帧中的 1%,无阻塞:约 400 帧中的 0.21645021645021645%,这似乎是由打开窗口或其他一些潜在的 CPU 密集型操作引起的由用户。
所以这是相当罕见的,但问题是这根本不应该发生。如果你想用它们做有用的事情,模拟时间、动画等,那么你需要这些时间才有意义。
我已经考虑了人们所说的话,但也许我仍然不明白事情是如何运作的。如果这一切都符合规范,我会喜欢一些伪代码来巩固我的想法。
更重要的是,如果有人对我如何解决这些问题有任何建议,那就太好了。我唯一能想到的就是每帧进行我自己的performance.now() 测量并使用它——但这似乎有点浪费,让它每帧有效地运行两次,在任何触发事件之上等等。
【问题讨论】:
-
我在你的 sn-p 中添加了一个停止状态。随意回滚,但这样代码实际上会在某个时候完成:)。
-
不,这很酷。谢谢,@MikeMcCaughan。
标签: javascript timing requestanimationframe