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.