У меня setInterval
работает кусок кода 30 раз в секунду. Это прекрасно работает, однако, когда я выбираю другую вкладку (так что вкладка с моим кодом становится неактивной), setInterval
она почему-то устанавливается в состояние ожидания.
Я сделал этот упрощенный тестовый пример ( http://jsfiddle.net/7f6DX/3/ ):
var $div = $('div');
var a = 0;
setInterval(function() {
a++;
$div.css("left", a)
}, 1000 / 30);
Если вы запустите этот код, а затем переключитесь на другую вкладку, подождите несколько секунд и вернетесь назад, анимация продолжится в том же положении, в каком она была при переходе на другую вкладку. Таким образом, анимация не запускается 30 раз в секунду, если вкладка неактивна. Это можно подтвердить, посчитав количество раз, которое setInterval
функция вызывается каждую секунду - это будет не 30, а всего 1 или 2, если вкладка неактивна.
Я предполагаю, что это сделано специально для улучшения производительности, но есть ли способ отключить это поведение? Это на самом деле недостаток в моем сценарии.
Date
объектом, чтобы действительно увидеть , сколько времени прошло.Date
. Таким образом, когда интервалы не запускаются быстро (по этой или другим причинам), анимация становится более резкой, а не медленной.Ответы:
В большинстве браузеров неактивные вкладки имеют низкий приоритет выполнения, и это может повлиять на таймеры JavaScript.
Если значения вашего перехода были рассчитаны с использованием реального времени, прошедшего между кадрами, а не с фиксированными приращениями на каждом интервале, вы не только обойдете эту проблему, но и сможете добиться более плавной анимации, используя requestAnimationFrame, так как он может получать до 60 кадров в секунду, если процессор не очень занят.
Вот ванильный пример JavaScript перехода анимированного свойства с использованием
requestAnimationFrame
:Для фоновых задач (не связанных с пользовательским интерфейсом)
@UpTheCreek комментарий:
Если у вас есть фоновые задачи, которые необходимо точно выполнять через определенные промежутки времени, вы можете использовать HTML5 Web Workers . Посмотрите ответ Море ниже для более подробной информации ...
CSS против JS "анимации"
Эту проблему и многие другие можно избежать, используя CSS-переходы / анимации вместо анимаций на основе JavaScript, что добавляет значительную нагрузку. Я бы порекомендовал этот плагин jQuery, который позволит вам использовать CSS-переходы так же, как и
animate()
методы.источник
before = now;
чтобы получить истекшее время с начала вместо конца предыдущего вызова. Обычно это то, что вы хотите при анимации. Как и сейчас, если выполнение функции интервала занимает 15elapsedTime
мс, при следующем вызове (когда активна вкладка) будет выдано 35 мс (вместо 50 мс, что является интервалом).Я столкнулся с той же проблемой с затуханием звука и проигрывателем HTML5. Он застрял, когда вкладка стала неактивной. Поэтому я обнаружил, что WebWorker разрешено использовать интервалы / тайм-ауты без ограничений. Я использую это, чтобы разместить «галочки» в основной JavaScript.
Код WebWorkers:
Основной Javascript:
источник
Существует решение использовать веб-работников (как упоминалось ранее), потому что они работают в отдельном процессе и не замедляются
Я написал крошечный скрипт, который можно использовать без изменений в вашем коде - он просто переопределяет функции setTimeout, clearTimeout, setInterval, clearInterval.
Просто включите его перед всем вашим кодом.
больше информации здесь
источник
Просто сделай это:
Неактивные вкладки браузера буферизуют некоторые функции
setInterval
илиsetTimeout
.stop(true,true)
остановит все буферизованные события и сразу выполнит только последнюю анимацию.window.setTimeout()
Метод Теперь зажимы для отправки не более одного тайма - аута в секунду в неактивных вкладках. Кроме того, теперь он ограничивает вложенные тайм-ауты наименьшим значением, допустимым спецификацией HTML5: 4 мс (вместо 10 мс, которые он использовал для ограничения).источник
Я думаю, что лучшее понимание этой проблемы в следующем примере: http://jsfiddle.net/TAHDb/
Я делаю простую вещь здесь:
Сделайте интервал в 1 секунду, и каждый раз скрывайте первый промежуток, перемещайте его до последнего и показывайте второй промежуток.
Если вы остаетесь на странице, она работает так, как положено. Но если вы прячете вкладку в течение нескольких секунд, когда вы вернетесь, вы увидите усталую вещь.
Как и все события, которые не произошли в то время, когда вы были неактивны, произойдут все за 1 раз. поэтому на несколько секунд вы получите как X событий. они настолько быстрые, что можно увидеть все 6 участков одновременно.
Таким образом, он показывает, что хром только задерживает события, поэтому, когда вы вернетесь назад, все события произойдут, но все сразу ...
Практическое приложение, где это происходит, для простого слайд-шоу. Представьте, что числа - это изображения, и если пользователь вернется со скрытой вкладкой, когда он вернется, он увидит все плавающие изображения.
Чтобы исправить это, используйте стоп (true, true), как сказал pimvdb. Это очистит очередь событий.
источник
requestAnimationFrame
что jQuery используется. Из-за некоторых причуд (как этот), они удалили это. В 1.7 вы не видите такого поведения. jsfiddle.net/TAHDb/1 . Поскольку интервал составляет один раз в секунду, это фактически не влияет на опубликованную мной проблему, поскольку максимум для неактивных вкладок также составляет один раз в секунду, так что это не имеет значения.Для меня не важно воспроизводить звук в фоновом режиме, как для других, моя проблема была в том, что у меня были некоторые анимации, и они действовали как сумасшедшие, когда вы были на других вкладках и возвращались к ним. Мое решение было поместить эти анимации внутрь, если это предотвращает неактивную вкладку :
благодаря этому моя анимация работала, только если была активна вкладка. Я надеюсь, что это поможет кому-то в моем случае.
источник
setInterval(() => !document.hidden && myfunc(), 1000)
и это работает отличноИ то
setInterval
и другоеrequestAnimationFrame
не работает, когда вкладка неактивна или работает, но не в нужные периоды. Решение состоит в том, чтобы использовать другой источник для временных событий. Например, веб-сокеты или веб-работники - это два источника событий, которые прекрасно работают, когда вкладка неактивна. Поэтому не нужно переносить весь ваш код на веб-работника, просто используйте работника в качестве источника временных событий:,
Ссылка jsfiddle этого образца.
источник
Сильно под влиянием библиотеки Руслана Тушова, я создал свою маленькую библиотеку . Просто добавьте скрипт в,
<head>
и он будет исправленsetInterval
иsetTimeout
с теми, которые используютWebWorker
.источник
Воспроизведение аудиофайла обеспечивает полную производительность Javascript в фоновом режиме.
Для меня это было самое простое и наименее навязчивое решение - кроме воспроизведения слабого / почти пустого звука, нет других потенциальных побочных эффектов
Вы можете найти подробности здесь: https://stackoverflow.com/a/51191818/914546
(Из других ответов я вижу, что некоторые люди используют разные свойства тэга Audio, мне интересно, возможно ли использовать тэг Audio для полной производительности, без какого-либо воспроизведения)
источник
Примечание: это решение не подходит, если вам нравится, когда ваш интервал работает на фоне, например, при воспроизведении аудио или ... но если вы не уверены, например, что ваша анимация не работает должным образом при возврате на вашу страницу (вкладку), это хорошее решение.
Есть много способов достижения этой цели, может быть, «WebWorkers» является самым стандартным, но, конечно, он не самый простой и удобный, особенно если вам не хватает времени, поэтому вы можете попробовать это следующим образом:
►Основная концепция:
1 - создайте имя для своего интервала (или анимации) и установите интервал (анимацию), чтобы он запускался при первом открытии вашей страницы пользователем:
var interval_id = setInterval(your_func, 3000);
2-,
$(window).focus(function() {});
и$(window).blur(function() {});
вы можетеclearInterval(interval_id)
каждый раз отключать браузер (вкладку) и повторно запускать интервал (анимацию) каждый раз, когда браузер (вкладка) снова активируетсяinterval_id = setInterval();
► Образец кода:
источник
Это довольно старый вопрос, но я столкнулся с той же проблемой.
Если вы работаете в Интернете на Chrome, вы можете прочитать этот пост Фоновые вкладки в Chrome 57 .
Обычно интервальный таймер может работать, если он не исчерпал бюджет таймера.
Потребление бюджета основано на использовании времени процессора для выполнения задачи в таймере.
Исходя из моего сценария, я рисую видео на холст и транспортирую в WebRTC.
Видео-соединение webrtc будет обновляться, даже если вкладка неактивна.
Однако вы должны использовать
setInterval
вместоrequestAnimationFrame
.это не рекомендуется для рендеринга пользовательского интерфейса, хотя.
Было бы лучше выслушать
visibilityChange
событие и изменить механизм рендеринга соответственно.Кроме того, вы можете попробовать @ kaan-soral, и он должен работать на основе документации.
источник
Вот мое грубое решение
источник
postMessageHandler
Вызывает свое собственное событие он обработка, тем самым бесконечный цикл , который не блокирует пользовательский интерфейс. И пока он бесконечно зацикливается, он проверяет каждую обработку событий, есть ли функция тайм-аута или интервала для запуска.Мне удалось вызвать функцию обратного вызова минимум за 250 мс, используя звуковую метку и обработав событие ontimeupdate. Его вызывали 3-4 раза в секунду. Лучше, чем одна секунда отстает setTimeout
источник