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:
- ios 5 met en pause javascript lorsque tab n'est pas actif
-
setInterval
etsetTimeout
le délai est réduit lorsque les onglets ne sont pas actifs - on dirait que cela vient de commencer à apparaître récemment et peut gâcher les tests unitaires de Jasmine, autour d'autres choses. -
requestAnimationFrame
est ralenti lorsque tab n'est pas actif (raisonnable, ne peut pas penser à pourquoi cela affecterait trop quelqu'un)
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)?
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
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).