requestAnimationFrame срабатывает гораздо чаще, чем 60 кадров в секунду

Я использую requestAnimationFrame для анимации части моей страницы при перемещении мыши. Одна проблема, с которой я столкнулся сейчас, заключается в том, что он вызывает код рисования гораздо чаще, чем ожидалось, 60 раз в секунду (частота обновления моего монитора), если события перемещения мыши происходят быстрее, чем это.

Кажется, это зависит от мыши, которую вы используете, но с моей текущей я могу легко получить 10 событий перемещения мыши внутри одного кадра, если я перемещу ее относительно быстро. Насколько я понимаю, requestAnimationFrame должен запускать функцию рисования только один раз за кадр, независимо от того, как часто она вызывается.

Теперь, вызывая мой код рисования 10 раз в одном кадре, очевидно, это ужасно для производительности, поэтому мне нужно от этого избавиться. Нужно ли обрабатывать это вручную? Мое понимание requestAnimationFrame неверно, и это правильное поведение, или что я здесь упускаю? Как должен работать requestAnimationFrame?

1 ответ

Решение

Насколько я понимаю, requestAnimationFrame должен запускать функцию рисования только один раз за кадр, независимо от того, как часто она вызывается.

Вот где ваше понимание ввело вас в заблуждение.

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.

Другие вопросы по тегам