Производительность Javascript при работе на неконцентрированной вкладке

Похоже, что произошла смена какой-либо последней версии Chrome и Firefox *, и теперь выполнение Javascript, по-видимому, отличается от того, когда вкладка, в которой он выполняется, не является в настоящее время сосредоточенной.

Когда я запускаю тесты модуля Javascript, они обычно занимают около 20 секунд, но теперь, когда вкладка не сфокусирована, она занимает более 2000 секунд. Странно, однако, что время выполнения для каждого отдельного теста не затрагивается (большинство из них все еще составляет < 10ms). Я использую тестовый бегун, добавляя setTimeout(0) между запуском каждого теста, чтобы браузер не запирался во время выполнения, и поэтому кажется вероятным виновником.

Есть ли способ сказать движку Javascript не "дезоритизировать" эту вкладку? Приятно иметь возможность запускать мои тесты в фоновом режиме, не заставляя себя смотреть...

* Извините, мне все равно, чтобы попытаться установить старые версии, чтобы найти, когда это началось. По крайней мере, сейчас это происходит на Firefox 5.0 и Chrome 12.

Ответ 1

setTimeout и setInterval были отключены до минимума 1000 мс в неконцентрированных вкладках. Здесь - это отчет Bugzilla, в котором упоминается об этом. И вот аналогичный отчет Chromium bug. Я считаю, что это так в Firefox 5 и в Chrome с версии 11.

Согласно MDN:

В (Firefox 5.0/Thunderbird 5.0) и Chrome 11, тайм-ауты зажимаются до стрельба не чаще одного раза за второй (1000 мс) на неактивных вкладках; видеть ошибка 633421 для получения дополнительной информации о это в Mozilla или crbug.com/66078 для подробнее об этом в Chrome.

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

Ответ 2

Для Firefox, в частности, вы можете изменить предпочтение dom.min_background_timeout_value в about:config к числу ваших предпочтений в профиле, который вы используете для запуска тестов. Я бы не предложил делать это в вашем профиле просмотра по умолчанию, хотя: причина высокого зажима заключается в том, что он сокращает веб-сайты на вкладках фона, пережевывая CPU, обновляя глупые тики и т.д.

Ответ 3

Сделанное изменение состояло в том, чтобы увеличить (по большому счету) минимальное значение таймаута. Насколько мне известно, нет способа контролировать это; это во внутренностях реализации таймера. И Chrome, и Firefox делают это сейчас, возможно, Safari тоже.

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

Ответ 4

Я мог бы обойти это с помощью нескольких setInterval():

var setRealInterval = function(callback, interval) {
    var minBrowserInterval = 1000
    var setIntervalsCount = Math.max(1, minBrowserInterval / interval)
    for (var i = 0; i < setIntervalsCount; i++) {
        ;(function(i) {
            setTimeout(function() {
                setInterval(callback, interval * setIntervalsCount)
            }, i * interval)
        })(i)
    }
}