Как определить лучшую «частоту кадров» (задержка setInterval) для использования в цикле анимации JavaScript? - PullRequest
26 голосов
/ 30 мая 2010

Когда вы пишете анимацию JavaScript, вы, конечно, делаете цикл, используя setInterval (или повторный setTimeout). Но какую задержку лучше всего использовать в вызовах setInterval / setTimeout?

На странице jQuery API для функции .animate () пользователь "fbogner" говорит:

Просто, если кому-то интересно: анимации «визуализируются» с использованием setInterval со временем из 13 мс. Это довольно быстро! Самый быстрый интервал Chrome составляет около 10 мс. Все остальные браузеры "сэмплируют" примерно 20-30 мс.

Есть идеи, как jQuery решил использовать это конкретное число?


Началось вознаграждение. Я надеюсь, что кто-то со знанием исходного кода Chromium или Firefox сможет предоставить некоторые неопровержимые факты, которые могут подтвердить решение конкретной частоты кадров. Или, возможно, список анимаций (или рамок) и их задержек. Я считаю, что это дает интересную возможность провести небольшое исследование.


Интересно - я просто нашел время, чтобы посмотреть на источник Pac-Man * 1018 от Google, чтобы увидеть, что они сделали. Они устанавливают массив возможных FPS (90, 45, 30), начинают с первого, а затем каждый кадр проверяют «медленность» кадра (количество, превышающее выделенное время). Если медленность превышает 50 мс в 20 раз, частота кадров снижается до следующей в списке (90 -> 45, 45 -> 30). Похоже, что частота кадров никогда не повышается, вероятно, потому что игра настолько недолговечна, что не стоит тратить время на ее кодирование.

О, и задержка setInterval, конечно, установлена ​​в 1000 / частота кадров. Фактически они используют setInterval, а не повторяющиеся setTimeouts.

Я думаю, что эта динамическая частота кадров довольно изящна!

Ответы [ 5 ]

17 голосов
/ 18 июня 2010

Рискну сказать, что значительная часть веб-пользователей использует мониторы, которые обновляются с частотой 60 Гц, что составляет один кадр каждые 16,66 мс. Таким образом, чтобы сделать монитор узким местом, вам нужно создавать кадры быстрее, чем 16,66 мс.

Есть две причины, по которым вы выбрали бы значение, например, 13 мс. Во-первых, браузеру нужно немного времени, чтобы перекрасить экран (по моему опыту, не менее 1 мс). Например, каждые 15 мс обновляются, и это очень интересное число. Стандартное разрешение таймера в Windows составляет 15 мс (см. сообщение в блоге Джона Ресига ). Я подозреваю, что хорошо написанная анимация в 15 мс выглядит очень похожей на самых разных браузерах / операционных системах.

FWIW, fbogner это просто неправильно о браузерах не Chrome, запускающих setInterval каждые 20-30 мс. Я написал тест для измерения скорости запуска setInterval и получил следующие числа:

  • Хром - 4мс
  • Firefox 3,5 - 15 мс
  • IE6 - 15 мс
  • IE8 - 15 мс
5 голосов
/ 17 июня 2010

Псевдокод для этого:

FPS_WANTED = 25 
(just a number, it can be changed while executing, or it can be constant)

TIME_OF_DRAWING = 1000/FPS_WANTED 
(this is in milliseconds, I believe it is accurate enough) 
( should be updated when FPS_WANTED changes)

UntilTheUserLeavesTheDrawingApplication()
{

  time1 = getTime();
  doAnimation();
  time2 = getTime();
  animationTime = time2-time1;

  if (animationTime > TIME_OF_DRAWING)
  {
     [the FPS_WANTED cannot be reached]
     You can:
     1. Decrease the number of FPS to see if a lower framerate can be achieved
     2. Do nothing because you want to get all you can from the CPU
  }
  else
  {
     [the FPS can be reached - you can decide to]
     1. wait(TIME_OF_DRAWING-animationTime) - to keep a constant framerate of FPS_WANTED
     2. increase framerate if you want
     3. Do nothing because you want to get all you can from the CPU
  }

}

Конечно, возможны варианты, но это основной алгоритм, который действует в любом случае анимации.

3 голосов
/ 31 мая 2010

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

Например, если вы хотите скользить делителем по странице в течение секунды, так что это хороший эффект и своевременный. Вы бы пропустили координаты и имели бы достаточно короткое время цикла, чтобы эффект был заметным, но не скачкообразным.

Так что это метод проб и ошибок (из-за необходимости учитывать работу, время и возможности браузера). Так что это выглядит не только красиво в одном браузере.

2 голосов
/ 17 июня 2010

Число, указанное fbogner, было проверено. Браузеры в определенной степени ограничивают js-активность, чтобы ее можно было использовать каждый раз.

Если ваш javascript можно будет запускать каждые 5 мсек, у среды выполнения браузера будет гораздо меньше времени процессора, чтобы обновить рендеринг или отреагировать на пользовательский ввод (щелчки), потому что выполнение javascript блокирует браузер.

Я думаю, что chrome-dev позволяют вам запускать ваш javascript с гораздо более короткими интервалами, чем другие браузеры, потому что их V8-Javascript-Engine компилирует JavaScript, и, следовательно, он работает быстрее, и браузер будет блокироваться до тех пор, пока интерпретируется JS-кода.

Но движок не только намного быстрее, чтобы позволить более короткие интервалы, которые разработчики, безусловно, проверили, что является наилучшим из возможных кратчайших интервалов, чтобы позволить короткие интервалы и не блокировать браузер на долгое время

1 голос
/ 31 мая 2010

Не знаю причины временного интервала jQuery, поскольку 13 мс переводится в 80 кадров в секунду, что очень быстро. «Стандартные» кадры в секунду, которые используются в фильмах и т. Д., Составляют 25 кадров в секунду и достаточно быстры, чтобы человеческий глаз не заметил дрожания. 25fps означает 40 мс, поэтому, чтобы ответить на ваш вопрос: для анимации достаточно всего 40 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...