Comment les navigateurs mettent-ils en pause/modifient-ils Javascript lorsque l'onglet ou la fenêtre n'est pas actif?

Contexte: je fais des tests d'interface utilisateur qui doivent détecter si les gens font attention ou non. Mais, cette question Est Pas à propos de L'API de visibilité de page .

Plus précisément, j'aimerais savoir comment mon code Javascript sera affecté si l'onglet actuel n'est pas actif, ou si la fenêtre du navigateur n'est pas active, dans différents navigateurs. J'ai déterré ce qui suit jusqu'à présent:

J'ai les questions suivantes:

  • autres que les navigateurs mobiles, les navigateurs de bureau interrompent-ils l'exécution JS lorsqu'un onglet n'est pas actif? Quand et quels navigateurs?
  • quels navigateurs réduisent la répétition de setInterval? Est-il simplement réduit à une limite ou à un pourcentage? Par exemple, si j'ai une répétition de 10ms par rapport à une répétition de 5000ms, comment chacun sera-t-il affecté?
  • ces changements se produisent-ils si la fenêtre {[33] } est floue, par opposition à l'onglet? (J'imagine que ce serait plus difficile à détecter, car cela nécessite L'API du système d'exploitation.)
  • , y a d'autres effets qui ne seraient pas observés dans un onglet actif? Pourraient-ils gâcher les choses serait-il exécuté correctement (c'est-à-dire les tests Jasmin susmentionnés)?
141
demandé sur Community 2013-04-08 09:36:30

2 réponses

Test Un

J'ai écrit un test spécifiquement à cette fin:
Distribution de fréquence D'images: setInterval vs requestAnimationFrame

Remarque: Ce test est assez gourmand en CPU. requestAnimationFrame N'est pas pris en charge par IE 9 - et Opera 12-.

Le test enregistre le temps réel qu'il faut pour qu'un setInterval et requestAnimationFrame s'exécute dans différents navigateurs, et vous donne les résultats sous la forme d'une distribution. Vous pouvez modifier le nombre de millisecondes pour setInterval pour voir comment il fonctionne sous différents réglages. setTimeout fonctionne de la même manière qu'un setInterval en ce qui concerne les retards. {[3] } généralement par défaut à la 60fps en fonction du navigateur. Pour voir ce qui se passe lorsque vous passez à un onglet différent ou que vous avez une fenêtre inactive, ouvrez simplement la page, passez à un onglet différent et attendez un moment. Il continuera à enregistrer le temps réel qu'il faut pour ces fonctions dans un onglet inactif.

Deux

Une autre façon de le tester est de consigner l'horodatage à plusieurs reprises avec setInterval et requestAnimationFrame et affichez-le dans une console détachée. Vous pouvez voir à quelle fréquence il est mis à jour (ou s'il est jamais mis à jour) lorsque vous rendez l'onglet ou la fenêtre inactif.

Résultats

Chrome
Chrome limite l'intervalle minimum de setInterval à environ 1000 ms lorsque l'onglet est inactif. Si l'intervalle est supérieur à 1000 ms, il s'exécutera à l'intervalle spécifié. Il n'a pas d'importance si la fenêtre est floue, l'intervalle est limité uniquement lorsque vous passez à un onglet différent. requestAnimationFrame est mis en pause lorsque l'onglet est inactif.

// Provides control over the minimum timer interval for background tabs.
const double kBackgroundTabTimerInterval = 1.0;

https://codereview.chromium.org/6546021/patch/1001/2001

Firefox
Similaire à Chrome, Firefox limite l'intervalle minimum de setInterval à environ 1000 ms lorsque l'onglet (pas la fenêtre) est inactif. Cependant, requestAnimationFrame s'exécute exponentiellement plus lentement lorsque l'onglet est inactif, chaque image prenant 1s, 2s, 4s, 8s et ainsi de suite.

// 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

Internet Explorer
IE ne limite pas le délai dans setInterval lorsque l'onglet est inactif, mais il met en pause requestAnimationFrame dans les onglets inactifs. Peu importe si la fenêtre est floue ou non.

Bord
À partir du bord 14, setInterval est plafonné à 1000 ms dans les onglets inactifs. requestAnimationFrame est toujours en pause dans les onglets inactifs.

Safari
Tout comme Chrome, Safari caps setInterval à 1000ms lorsque l'onglet est inactif. {[3] } est également en pause.

Opéra
Depuis L'adoption du moteur Webkit, Opera présente le même comportement que Chrome. setInterval est plafonné à 1000ms et requestAnimationFrame est mis en pause lorsque l'onglet est inactif.

Résumé

Répétition des intervalles pour les onglets inactifs:

           setInterval     requestAnimationFrame
Chrome
9-         not affected    not supported
10         not affected    paused
11+        >=1000ms        paused

Firefox
3-         not affected    not supported
4          not affected    1s
5+         >=1000ms        2ns (n = number of frames since inactivity)

IE
9-         not affected    not supported
10+        not affected    paused

Edge
13-        not affected    paused
14+        >=1000ms        paused

Safari
5-         not affected    not supported
6          not affected    paused
7+         >=1000ms        paused

Opera
12-        not affected    not supported
15+        >=1000ms        paused
162
répondu Antony 2016-08-01 13:42:23

Ce que j'ai observé : sur les onglets inactifs dans Chrome, toutes vos setTimeout (doit être le même pour setInterval) en attente de moins de 1000ms sont arrondis à 1000ms. Je pense que les délais d'attente plus longs ne sont pas modifiés.

Semble être le comportement depuis Chrome 11 et Firefox 5.0 : https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs

De plus, Je ne pense pas qu'il se comporte de cette façon lorsque toute la fenêtre est inactive (mais semble assez facile à étudier).

10
répondu Paulloz 2013-04-10 20:18:30