requestAnimationFrame 触发频率远高于 60 fps

requestAnimationFrame fires far more often than 60 fps

我正在使用 requestAnimationFrame 在 mousemove 上为我的页面的一部分设置动画。我刚才遇到的一个问题是,如果 mousemove 事件发生得更快,它调用绘图代码的次数远远超过预期的每秒 60 次(我的显示器刷新率)。

这似乎取决于您使用的鼠标,但使用我当前使用的鼠标,如果我相对快速地移动它,我可以轻松地在同一帧内获得 10 个 mousemove 事件。我的理解是 requestAnimationFrame 应该只在每个 Frame 中触发一次绘图函数,无论调用它的频率如何。

现在,在一帧内调用我的绘图代码 10 次对性能来说显然很糟糕,所以我需要摆脱它。我必须按设计手动处理吗?我对 requestAnimationFrame 的理解是错误的,这是正确的行为,还是我在这里遗漏了什么? requestAnimationFrame 应该如何工作?

My understanding was that requestAnimationFrame should only trigger the drawing function once per Frame, no matter how often it is called.

这是你的理解误导了你。

requestAnimationFrame方法实际上会将所有函数堆叠起来并在同一帧中执行。

因此,如果您在同一帧中调用了 30 次 requestAnimationFrame(func),那么 func 将在下一帧中调用 30 次。 这些函数甚至似乎合并到同一个调用中,因为它们确实共享相同的 time 参数。

var funcA = function(time) {
  snippet.log('funcA executed at ' + time);
  snippet.log('exact time: ' + performance.now())
}
var funcB = function(time) {
  snippet.log('funcB executed at ' + time);
  snippet.log('exact time: ' + performance.now())
}


snippet.log('funcA stacked at ' + performance.now())
requestAnimationFrame(funcA);
// block the process for some time
var i = 0;
while (i++ < 10000000) {}

snippet.log('funcB stacked at ' + performance.now())
requestAnimationFrame(funcB);
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

为了避免它,例如要进行去抖动,您需要使用一些标记,您将在 rAF 执行时释放这些标记。