2014-09-30 1 views
3

requestAnimationFrame вызывается всякий раз, когда экран готов к перекрашиванию. На современных экранах частота обновления может быть намного выше 60 кадров в секунду. Если внутри этих вызовов будет много вещей, это может повлиять на общую производительность приложения.Должен ли запрос requestAnimationFrame отключать до 60 FPS?

Так что, мой вопрос: должен ли допуск на 60FPS доходить до requestAnimationFrame? Может ли человеческий глаз на самом деле сказать разницу между, например, 16 мс и задержкой переиздания 8 мс?

[UPDATE] Я закончил тем, что уменьшил его до 60FPS для повышения производительности на экранах с высокой частотой обновления. И предложил бы такой подход всем, у кого есть много вещей, идущих внутри вызовов rAF. Конечно, вы должны сами провести тестирование.

+1

Ну, если в этих обратных вызовах много вещей, то следующий кадр анимации обязательно будет задерживаться. «Рамка анимации» не привязана к частоте обновления экрана! – Bergi

+0

Спасибо за комментарий! Есть ли у вас какие-либо ссылки? – YemSalat

+0

Нет, и на самом деле я мог быть неверным (см. Цитату из ответа Клыда). Браузер умный и пытается синхронизировать частоту кадров (обратный вызов фрейма анимации анимации + reflow + redraw), при этом экран обновляется для плавного воспроизведения. Тем не менее, он будет автоматически дросселировать его, когда есть (слишком) много js работает на каждый кадр, батарея работает на низком уровне, вкладка не отображается и т. Д. – Bergi

ответ

4

По MDN он не обязательно должен быть 60 FPS.

Соответствующая цитата:

Это будет просить, что функция анимации вызываться перед браузер выполняет следующий перекрашивать. Количество обратных вызовов обычно 60 раз в секунду, но обычно соответствуют частоте обновления дисплея в большинстве веб-браузеров согласно рекомендации W3C. Скорость обратного вызова может быть уменьшена до меньшей скорости при работе в фоновых вкладках.

Что касается человеческого глаза, то можно отличить 60 против 120 FPS, это открытый и упрямый вопрос. Некоторые утверждают, что видят это, а другое - его невозможно. Разрешить конечному пользователю выбрать (или просто использовать свое оборудование в полном объеме), вероятно, лучше всего.

Как указано markE's comment. Ответный вызов requestAnimationFrame получает DOMHighResTimeStamp, который является точным таймером с высокой точностью, с «thousandth of a millisecond.». Используя эту метку времени и вычисляя дельта между кадрами, вы можете настроить частоту обновления до любого желаемого значения.

Ссылки:

Примечание: пожалуйста, не забудьте оставить комментарий решении любых downvotes, Ot они не являются полезной обратной связью.

+0

Я думаю, что конечный пользователь может не всегда знать о последствиях выполнения JS так много раз в секунду, я в основном обеспокоен тем, что JS является однопоточным, и если 'rAF' становится слишком« лагги »- это повлияет на все приложение а не только цикл перерисовывания.Но я думаю, мне нужно будет придумать некоторые тесты и убедиться в этом сами. – YemSalat

+0

Абсолютно. Вы также не обязательно хотите использовать «rAF» для синхронизации событий. Вместо этого для точного времени можно использовать ['performance.now()'] (https://developer.mozilla.org/en-US/docs/Web/API/Performance.now). Используя это, вы можете зажимать свои перерисовки на каждые *** n *** миллисекунды по вашему выбору. – klyd

+3

+1 за хороший ответ. Просто примечание ... теперь браузеры отправляют параметр временной метки в RAF. Это означает, что вы можете вычислить прошедшее время с момента последнего цикла петли RAF. Это позволяет вам дросселировать RAF до нужного интервала ;-) – markE

0

Я думаю, что люди, имеющие 120-часовую или более высокую частоту кадров, знают, что для создания в два раза больше кадров требуется больше ресурсов.

Это и/или у них более мощные компьютеры, чем у большинства пользователей. У меня лично есть очень мощный компьютер, но два монитора на 60 Гц, и единственный парень, которого я знаю, который имеет дисплей с более высокой частотой кадров, чем 60 Гц, является профессиональным игроком, поэтому, очевидно, у него нет проблем с производительностью при просмотре веб-страниц.

Кроме того, люди, использующие очень высокие частоты кадров, привыкают к этому уровню текучести, и они могут заметить разницу (событие, если я в этом сомневаюсь).

Мои два цента: уважайте их предпочтение наличию дисплея переполнения. Это то, что они хотят.

+0

Спасибо за ответ, но я думаю, что есть разница между простое перерисовка экрана и перерисовка экрана + вызов функции JS. Кроме того, высокая частота обновления не обязательно означает хорошее аппаратное обеспечение, например - все дисплеи, где я работаю, составляют 144 Гц, но некоторые из машин 7-8 лет. – YemSalat

-2

По умолчанию, я думаю, что это хорошо, чтобы ограничить частоту кадров до 60 Гц, так как:

• Высокая частота кадров, тем больше тепла, поэтому (процессор) шум вентилятора будет раздражать.
• Для большинства игр никто не заметит.
• это легко сделать.
• Для тех, кто имеет экологические проблемы, высокие частоты fps потребляют больше энергии (==> больше CO2).

О визуальном интересе 120 Гц:
Для 2D-игр, где на каждом кадре фактически изменяется только небольшое количество экрана, это мало чем интересует.
Для 3D-игр, особенно ориентированных на реалистичность, использование 120 Гц позволяет получить более «кинематографический» опыт.
Почему?
==> Большинство 3D-рендерингов визуализируют сцену в точке во времени, так что вы видите последовательность «совершенных» неподвижных изображений.
С другой стороны, настоящая камера будет, как человеческий глаз, оставаться открытой в течение нескольких миллисекунд, поэтому движения, происходящие в это время, оставят след на изображении, обеспечивая более верный жизненный опыт.

Граница 60 Гц достаточно, чтобы обмануть глаз вокруг движения, так что приносит 120 Гц + экран, так что экран настолько быстр, что не может следовать за ним, и у вас снова есть эффект камеры/глазного следа.

код выглядит следующим образом:

var minFrame = 13; 
var maxFrame = 19; 
var typicalFrame = 16; 

var gameTime = 0; 

var lastDrawTime = -1; 

animate(drawTime) { 
    requestAnimationFrame(animate); 
    var dt = drawTime - lastDrawTime; 
    lastDrawTime = drawTime ; 
    if (dt<minFrame) return; 
    if (dt>maxFrame) dt=typicalFrame; // in case of a tab-out 
    gameTime+=dt; 
    // ... 
} 

function lauchAnimation() { 
    requestAnimationFrame (function(t) { lastDrawTime = t; 
              requestAnimationFrame(animate); });   
} 

RQ1: Когда вы ограничиваете кадров в секунду, вы должны позаботиться о том, что частота кадров не стабильной на всех в браузере.
Таким образом, даже приложением, ничего не выполняющим, на экране 60 Гц, имеет длительность кадра, которая может идти от 14 мс до 19 мс. (!!!!) Поэтому вы должны взять некоторый запас при ограничении частоты кадров до некоторого значения.

Rq2: В приведенном выше примере «TypicalFrame» заменяется собственной частотой кадров экрана (которую вы должны вычислить самостоятельно).

+2

Нет причин для этого вручную. Если браузер (кто является авторитетным!) Считает, что он должен экономить энергию или позволить процессору остыть, он автоматически уменьшит частоту кадров. – Bergi

+0

@Bergi: false. – GameAlchemist

+1

Действительно? Я действительно понял http://www.w3.org/TR/animation-timing/: «* Использование этого API должно привести к более правильному использованию процессора браузером. *« Вот так. – Bergi