[解決済み] タブやウィンドウがアクティブでないとき、ブラウザはどのようにJavascriptを一時停止/変更するのですか?
質問
背景 私は、人々が注意を払っているかどうかを検出する必要があるいくつかのユーザーインターフェイスのテストを行っています。しかし、この質問は ではない について ページ可視化API .
具体的には、異なるブラウザで現在のタブがアクティブでない場合、またはブラウザウィンドウがアクティブでない場合、私のJavascriptコードがどのように影響を受けるかを知りたいのです。今のところ、次のようなことを掘り起こしました。
- ios 5 では、タブがアクティブでないときに javascript が一時停止されます。
-
setInterval
とsetTimeout
タブがアクティブでない場合、遅延は減少します - これは最近現れ始めたようで、Jasmineのユニットテストを混乱させることがあるようです。 -
requestAnimationFrame
は、タブがアクティブでないときに遅くなります (合理的です。これが誰かに大きな影響を与える理由は思いつきません)。
以下のような質問があります。
- モバイルブラウザ以外のデスクトップ用ブラウザでは、タブがアクティブでないときにJSの実行が一時停止されることはありますか?いつ、どのブラウザで?
-
どのブラウザが
setInterval
の繰り返しですか?それは単に限界まで減らされるのか、それとも何%か減らされるのか?例えば、10msのリピートと5000msのリピートがあった場合、それぞれどのような影響があるのでしょうか? - これらの変更は ウィンドウ は、タブだけでなく、フォーカスから外れていますか?(OSのAPIを必要とするため、検出が難しくなると想像しています)。
- その他、アクティブなタブでは観測されないような効果はありますか?そうでなければ正しく実行されるもの(前述のJasmineのテストなど)を台無しにしてしまう可能性はありませんか?
解決方法は?
テスト1
この目的のために、特別にテストを書きました。
フレームレート分布:setIntervalとrequestAnimationFrameの比較
注:このテストはかなりCPUに負荷がかかります。
requestAnimationFrame
はIE 9-とOpera 12-でサポートされていません。
このテストでは
setInterval
と
requestAnimationFrame
を異なるブラウザで実行させ、その結果を分布の形で与えます。のミリ秒数を変更することができます。
setInterval
をクリックすると、異なる設定での動作を確認できます。
setTimeout
と同じように動作します。
setInterval
は、ディレイに関して
requestAnimationFrame
は、ブラウザによって異なりますが、通常60fpsに設定されます。別のタブに切り替えたり、非アクティブなウィンドウがある場合にどうなるかを確認するには、ページを開いて別のタブに切り替え、しばらく待つだけです。非アクティブなタブでこれらの機能にかかる実際の時間を記録し続けます。
テスト2
もう一つのテスト方法は、タイムスタンプを繰り返し記録するために
setInterval
と
requestAnimationFrame
を作成し、切り離したコンソールで表示します。タブやウィンドウを非アクティブにすると、更新頻度(あるいは更新されたかどうか)を確認できます。
成果
クローム
の最小間隔を制限しています。
setInterval
を、タブが非アクティブの時に1000ms程度に設定します。1000msを超えると、指定した間隔で実行されます。ウィンドウのフォーカスが外れても関係なく、別のタブに切り替えたときだけ間隔が制限されます。
requestAnimationFrame
は、タブが非アクティブのときに一時停止します。
// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;
https://codereview.chromium.org/6546021/patch/1001/2001
ファイアフォックス
Chromeと同様に、Firefoxでも
setInterval
を、タブ(ウィンドウではない)が非アクティブのとき、1000ms 程度に設定します。しかし
requestAnimationFrame
は、1フレームに1秒、2秒、4秒、8秒と、指数関数的に遅くなります。
// 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
インターネットエクスプローラー
IEでは、遅延を制限しない
setInterval
は、タブが非アクティブのときは一時停止しますが
requestAnimationFrame
を非アクティブなタブで使用することができます。ウィンドウのフォーカスが外れているかどうかは関係ありません。
エッジ
Edge14からスタート。
setInterval
は、非アクティブなタブでは 1000 ミリ秒が上限となります。
requestAnimationFrame
は、非アクティブなタブでは常に一時停止します。
サファリ
Chromeと同様、Safariのキャップ
setInterval
を1000msに設定しています。
requestAnimationFrame
も一時停止されます。
オペラ
Webkitエンジンの採用により、OperaはChromeと同じ挙動を示すようになりました。
setInterval
は1000msを上限とし
requestAnimationFrame
は、タブが非アクティブのときに一時停止されます。
概要
非アクティブなタブのインターバルを繰り返す。
setInterval requestAnimationFrame クローム 9- 影響なし サポートなし 10 影響なし 一時停止 11+ >=1000msのポーズ付き ファイアフォックス 3- 影響なし サポートなし 4 影響なし 1s 5+ >=1000ms 2 n s (n = 非アクティブからのフレーム数) IE 9- 影響なし サポートなし 10以上 影響なし 一時停止 エッジ 13- 影響なし 一時停止 14+ >=1000ms ポーズ サファリ 5- 影響なし サポートなし 6 影響なし 一時停止 7+ >=1000msのポーズ付き オペラ 12- 影響なし サポートなし 15回以上 >=1000msの一時停止
関連
-
要素ツリー制御によるvueTreeテーブル
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
HTML5 LocalStorage ローカルストレージとセッションストレージの使用法
-
[解決済み] JavaScriptで要素のクラスを変更するにはどうすればよいですか?
-
[解決済み] URLを新しいタブで開く(新しいウィンドウではない)
-
[解決済み] スクリプトタグ - 非同期と遅延
-
[解決済み] ブラウザのウィンドウが現在アクティブでないことを検出する方法はありますか?
-
[解決済み】JavaScriptの関数名を文字列で指定して実行する方法
-
[解決済み】JavaScriptで定義されていない変数を確認する方法
-
[解決済み】JavaScriptをタブではなく別ウィンドウで表示する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JSアレイループと効率解析の比較
-
HTML+CSS+JavaScriptで簡単な三目並べゲームを作成する。
-
JavaScriptのクロージャの説明
-
Vueにシンプルなメモ帳機能を実装
-
[解決済み] Error : 未定義のプロパティ 'map' を読み取ることができません。
-
[解決済み】GETできない / Nodejsエラー
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
JavaScriptのgetElementById()メソッド入門
-
[解決済み] ブラウザのウィンドウが現在アクティブでないことを検出する方法はありますか?