Как браузеры приостанавливают/меняют Javascript, если вкладка или окно неактивны?

Справочная информация. Я выполняю некоторые тесты пользовательского интерфейса, которые необходимо определить, обращают внимание люди или нет. Но этот вопрос < не API видимости страницы.

В частности, мне хотелось бы знать, как повлияет мой Javascript-код, если текущая вкладка не активна или окно браузера неактивно в разных браузерах. Я покал следующее:

У меня есть следующие вопросы:

  • В отличие от мобильных браузеров, настольные браузеры когда-либо приостанавливают выполнение JS, если вкладка не активна? Когда и какие браузеры?
  • Какие браузеры сокращают повторение setInterval? Это просто сокращено до предела или на процент? Например, если у меня есть 10 мс повторение по сравнению с повторением 5000 мс, как каждый из них будет затронут?
  • Выполняются ли эти изменения, если окно не в фокусе, а не только табуляция? (Я думаю, это будет сложнее обнаружить, так как для этого требуется API OS.)
  • Есть ли другие эффекты, которые не наблюдались бы на активной вкладке? Могут ли они испортить вещи, которые в противном случае выполнялись бы правильно (т.е. Вышеупомянутые тесты Жасмина)?

Ответ 1

Test One

Я специально написал для этой цели тест:
Распределение кадров: setInterval vs requestAnimationFrame

Примечание. Этот тест довольно интенсивен. requestAnimationFrame не поддерживается IE 9 и Opera 12 -.

Тест регистрирует фактическое время, необходимое для запуска setInterval и requestAnimationFrame в разных браузерах, и дает результаты в форме распространения. Вы можете изменить количество миллисекунд на setInterval, чтобы увидеть, как он работает под разными настройками. setTimeout работает аналогично a setInterval по отношению к задержкам. requestAnimationFrame обычно зависит от 60 кадров в секунду в зависимости от браузера. Чтобы узнать, что происходит при переключении на другую вкладку или в неактивном окне, просто откройте страницу, перейдите на другую вкладку и подождите некоторое время. Он будет продолжать регистрировать фактическое время, необходимое для этих функций, на неактивной вкладке.

Test Two

Еще один способ проверить это - повторить запись метки времени с помощью setInterval и requestAnimationFrame и просмотреть ее в отдельной консоли. Вы можете увидеть, как часто он обновляется (или если он когда-либо обновляется), когда вы делаете вкладку или окно неактивными.

Результаты

Chrome
Chrome ограничивает минимальный интервал setInterval примерно до 1000 мс, когда вкладка неактивна. Если интервал превышает 1000 мс, он будет работать с заданным интервалом. Неважно, если окно не в фокусе, интервал ограничен только при переключении на другую вкладку. requestAnimationFrame приостанавливается, когда вкладка неактивна.

// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;

https://codereview.chromium.org/6546021/patch/1001/2001

Firefox
Подобно Chrome, Firefox ограничивает минимальный интервал setInterval примерно до 1000 мс, когда вкладка (а не окно) неактивна. Тем не менее, requestAnimationFrame работает экспоненциально медленнее, когда вкладка неактивна, причем каждый кадр принимает 1s, 2s, 4s, 8s и т.д.

// The default shortest interval/timeout we permit
#define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
#define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms

https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296

Internet Explorer
IE не ограничивает задержку в setInterval, когда вкладка неактивна, но она приостанавливает requestAnimationFrame на неактивных вкладках. Не имеет значения, находится ли окно вне фокуса или нет.

Край
Начиная с края 14, setInterval ограничено 1000 мс на неактивных вкладках. requestAnimationFrame всегда приостанавливается на неактивных вкладках.

Safari
Так же, как Chrome, Safari caps setInterval на 1000 мс, когда вкладка неактивна. requestAnimationFrame также приостановлен.

Opera
С момента принятия движка Webkit Opera проявляет такое же поведение, как Chrome. setInterval ограничено 1000 мс, а requestAnimationFrame приостанавливается, когда вкладка неактивна.

Резюме

Интервалы повторения для неактивных вкладок:

           setInterval     requestAnimationFrame
Chrome
9-         not affected    not supported
10         not affected    paused
11+        >=1000ms        paused

Firefox
3-         not affected    not supported
4          not affected    1s
5+         >=1000ms        2ns (n = number of frames since inactivity)

IE
9-         not affected    not supported
10+        not affected    paused

Edge
13-        not affected    paused
14+        >=1000ms        paused

Safari
5-         not affected    not supported
6          not affected    paused
7+         >=1000ms        paused

Opera
12-        not affected    not supported
15+        >=1000ms        paused

Ответ 2

Что я наблюдал: на неактивных вкладках в Chrome все ваши setTimeout (должны быть одинаковыми для setInterval), ожидая, что менее 1000 мс округляются до 1000 мс. Я думаю, что длинные таймауты не изменяются.

Кажется, это поведение с Chrome 11 и Firefox 5.0: https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs

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