web-dev-qa-db-ja.com

Chrome:バックグラウンドタブでタイムアウト/間隔が一時停止しましたか?

このテスト を使用してsetTimeoutの精度をテストしていました。予想どおり、setTimeoutはあまり正確ではありませんが、ほとんどのアプライアンスでは劇的に不正確ではありません。ここでChromeでテストを実行し、バックグラウンドタブで実行するようにすると(別のタブに切り替えてそこを参照します)、テストに戻って結果を検査します(テストが終了した場合)それらは劇的に変化しています。タイムアウトがずっと遅くなっているようです。 FF4またはIE9でテストしたところ、これは発生しませんでした。

したがって、Chromeは、フォーカスのないタブでJavaScriptの実行を一時停止するか、少なくとも遅くするように見えます。この件については、ネット上で多くを見つけることができなかった。たとえば、XHR呼び出しとsetIntervalを使用してサーバー上で定期的にチェックするなど、バックグラウンドタスクを実行できないことを意味します(setIntervalに対して同じ動作が見られると思われる場合は、私と一緒です)。

誰もこれに遭遇しましたか?この一時停止/スローダウンの回避策はありますか?それをバグと呼びますか?

115
KooiInc

私は最近これについて尋ねましたが、これは設計上の動作です。タブが非アクティブの場合、最大で毎秒1回のみ関数が呼び出されます。 コード変更 です。

おそらくこれは助けになります: Chromeでタブが非アクティブなときにsetIntervalを動作させるにはどうすればよいですか?

TL; DR:使用Web Workers.

77
pimvdb

Web Workerは別のプロセスで実行され、速度が低下しないため、Web Workerを使用するソリューションがあります。

コードを変更せずに使用できる小さなスクリプトを作成しました-関数setTimeout、clearTimeout、setInterval、clearIntervalをオーバーライドするだけです

すべてのコードの前にそれを含めるだけです

http://github.com/turuslan/HackTimer

21
Ruslan Tushov

〜空の音を再生すると、ブラウザはパフォーマンスを維持するように強制されます-このコメントを読んだ後、私はそれを発見しました: タブがアクティブでない場合でもChromeでJavaScriptを通常の速度で実行する方法?

WebSocketを使用するブラウザゲームにはオンデマンドで無制限のパフォーマンスが必要なので、WebSocketを使用しても無制限のパフォーマンスが保証されないことを経験から知っていますが、テストからはオーディオファイルを再生することで確実になりそう

この目的のために作成した2つの空のオーディオループは次のとおりです。商業的に自由に使用できます: http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogghttp://adventure.land/sounds/loops/empty_loop_for_js_performance.wav

(それらには-58dbノイズが含まれ、-60dbは機能しません)

ユーザーの要求に応じて、Howler.jsで再生します: https://github.com/goldfire/howler.js

function performance_trick()
{
    if(sounds.empty) return sounds.empty.play();
    sounds.empty = new Howl({
        src: ['/sounds/loops/empty_loop_for_js_performance.ogg','/sounds/loops/empty_loop_for_js_performance.wav'],
        volume:0.5,
        autoplay: true, loop: true,
    });
}

デフォルトで完全なJavaScriptパフォーマンスをオン/オフする組み込みメソッドがないのは残念ですが、暗号マイナーはプロンプトなしでWeb Workersを使用してすべてのコンピューティングスレッドをハイジャックできます:|

4
Kaan Soral

worker-interval npmパッケージをリリースしました。このパッケージは、Chrome、Firefox、IEの非アクティブなタブでWeb-Workersを使用して非アクティブなタブで稼働を維持するsetIntervalおよびclearInterval実装です。

最新のブラウザ(Chrome、Firefox、IE)のほとんど、間隔(ウィンドウタイマー)は、非アクティブなタブで1秒に1回よりも頻繁に起動しないように制限されています。

詳細については、をご覧ください。

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Timeouts_and_intervals

1
gorkemcnr

JQueryコアを1.9.1に更新し、非アクティブなタブの間隔の不一致を解決しました。最初にそれを試してから、他のコードオーバーライドオプションを調べます。

1
Carey Estes

現在のミリ秒を取得し、それが関数が作成されたミリ秒と比較する私のソリューションです。間隔については、関数を実行するときにミリ秒を更新します。 IDで間隔/タイムアウトを取得することもできます。

<script>

var nowMillisTimeout = [];
var timeout = [];
var nowMillisInterval = [];
var interval = [];

function getCurrentMillis(){
    var d = new Date();
    var now = d.getHours()+""+d.getMinutes()+""+d.getSeconds()+""+d.getMilliseconds();
    return now;
}

function setAccurateTimeout(callbackfunction, millis, id=0){
    nowMillisTimeout[id] = getCurrentMillis();
    timeout[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisTimeout[id] + +millis)){callbackfunction.call(); clearInterval(timeout[id]);} }, 10);
}

function setAccurateInterval(callbackfunction, millis, id=0){
    nowMillisInterval[id] = getCurrentMillis();
    interval[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisInterval[id] + +millis)){callbackfunction.call(); nowMillisInterval[id] = getCurrentMillis();} }, 10);
}

//usage
setAccurateTimeout(function(){ console.log('test timeout'); }, 1000, 1);

setAccurateInterval(function(){ console.log('test interval'); }, 1000, 1);

</script>
0
SwiftNinjaPro