1. ホーム
  2. javascript

[解決済み] タブやウィンドウがアクティブでないとき、ブラウザはどのようにJavascriptを一時停止/変更するのですか?

2022-04-21 20:08:20

質問

背景 私は、人々が注意を払っているかどうかを検出する必要があるいくつかのユーザーインターフェイスのテストを行っています。しかし、この質問は ではない について ページ可視化API .

具体的には、異なるブラウザで現在のタブがアクティブでない場合、またはブラウザウィンドウがアクティブでない場合、私のJavascriptコードがどのように影響を受けるかを知りたいのです。今のところ、次のようなことを掘り起こしました。

以下のような質問があります。

  • モバイルブラウザ以外のデスクトップ用ブラウザでは、タブがアクティブでないときにJSの実行が一時停止されることはありますか?いつ、どのブラウザで?
  • どのブラウザが setInterval の繰り返しですか?それは単に限界まで減らされるのか、それとも何%か減らされるのか?例えば、10msのリピートと5000msのリピートがあった場合、それぞれどのような影響があるのでしょうか?
  • これらの変更は ウィンドウ は、タブだけでなく、フォーカスから外れていますか?(OSのAPIを必要とするため、検出が難しくなると想像しています)。
  • その他、アクティブなタブでは観測されないような効果はありますか?そうでなければ正しく実行されるもの(前述のJasmineのテストなど)を台無しにしてしまう可能性はありませんか?

解決方法は?

テスト1

この目的のために、特別にテストを書きました。

フレームレート分布:setIntervalとrequestAnimationFrameの比較

注:このテストはかなりCPUに負荷がかかります。 requestAnimationFrame はIE 9-とOpera 12-でサポートされていません。

このテストでは setIntervalrequestAnimationFrame を異なるブラウザで実行させ、その結果を分布の形で与えます。のミリ秒数を変更することができます。 setInterval をクリックすると、異なる設定での動作を確認できます。 setTimeout と同じように動作します。 setInterval は、ディレイに関して requestAnimationFrame は、ブラウザによって異なりますが、通常60fpsに設定されます。別のタブに切り替えたり、非アクティブなウィンドウがある場合にどうなるかを確認するには、ページを開いて別のタブに切り替え、しばらく待つだけです。非アクティブなタブでこれらの機能にかかる実際の時間を記録し続けます。

テスト2

もう一つのテスト方法は、タイムスタンプを繰り返し記録するために setIntervalrequestAnimationFrame を作成し、切り離したコンソールで表示します。タブやウィンドウを非アクティブにすると、更新頻度(あるいは更新されたかどうか)を確認できます。

成果

クローム

の最小間隔を制限しています。 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の一時停止