Contexte: Je fais des tests d'interface utilisateur qui doivent détecter si des personnes sont attentives ou non. Mais, cette question concerne pas environ l'API de visibilité de la page .
Plus précisément, j'aimerais savoir comment mon code Javascript sera affecté si l'onglet en cours n'est pas actif ou si la fenêtre du navigateur n'est pas active dans différents navigateurs. J'ai déterré les éléments suivants jusqu'à présent:
setInterval
et setTimeout
le délai est réduit lorsque les onglets ne sont pas actifs - semble que cela a commencé à apparaître récemment et peut gâcher les tests unitaires Jasmine, entre autres choses.requestAnimationFrame
est ralenti quand la tabulation n'est pas active (raisonnable, je ne vois pas pourquoi cela toucherait trop quelqu'un)J'ai les questions suivantes:
setInterval
? Est-ce simplement réduit à une limite ou à un pourcentage? Par exemple, si j'ai une répétition de 10 ms par rapport à une répétition de 5000 ms, comment cela sera-t-il affecté?J'ai écrit un test spécialement à cet effet:
Distribution de la fréquence d'images: setInterval vs requestAnimationFrame
Remarque: ce test nécessite beaucoup de ressources processeur. requestAnimationFrame
n'est pas supporté par IE 9- et Opera 12-.).
Le test enregistre le temps réel nécessaire pour que 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 s'exécute sous différents paramètres. setTimeout
fonctionne de la même manière qu'un setInterval
en ce qui concerne les retards. requestAnimationFrame
utilise généralement la valeur par défaut de 60 images par seconde en fonction du navigateur. Pour voir ce qui se passe lorsque vous passez à un autre onglet ou que vous avez une fenêtre inactive, ouvrez simplement la page, passez à un autre onglet et attendez un moment. Il continuera à enregistrer la durée réelle nécessaire à ces fonctions dans un onglet inactif.
Une autre façon de le tester consiste à enregistrer l'horodatage à plusieurs reprises avec setInterval
et requestAnimationFrame
, puis à l'afficher dans une console séparée. Vous pouvez voir à quelle fréquence il est mis à jour (ou s'il l'est jamais) lorsque vous désactivez l'onglet ou la fenêtre.
Chrome
Chrome limite l'intervalle minimal 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é. Peu importe que la fenêtre soit floue, l'intervalle n'est limité que lorsque vous passez à un autre onglet. requestAnimationFrame
est suspendu 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
Semblable à Chrome, Firefox limite l’intervalle minimum de setInterval
à environ 1000 ms lorsque l’onglet (et non la fenêtre) est inactif. Cependant, requestAnimationFrame
s'exécute de manière exponentielle plus lente lorsque l'onglet est inactif, chaque image prenant 1, 2, 4, 8, etc.
// 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 des onglets inactifs. Peu importe que la fenêtre soit floue ou non.
Edge
Depuis Edge 14, setInterval
est limité à 1000 ms dans les onglets inactifs. requestAnimationFrame
est toujours en pause dans les onglets inactifs.
Safari
À l’instar de Chrome, Safari met setInterval
à 1000 ms lorsque l’onglet est inactif. requestAnimationFrame
est également en pause.
Opera
Depuis l’adoption du moteur Webkit, Opera présente le même comportement que Chrome. setInterval
est limité à 1000 ms et requestAnimationFrame
est suspendu lorsque l'onglet est inactif.
Intervalles répétés pour les onglets inactifs:
setIntervalrequestAnimationFrameChrome 9- non affecté non pris en charge 10 non affecté en pause 11+> = 1000 ms en pause Firefox 3- non affecté non pris en charge 4 non affecté 1s 5+> = 1000ms 2ns (n = nombre d'images depuis l'inactivité) IE 9- non affecté non pris en charge 10+ non affecté mis en pause Bord 13- non affecté en pause 14+> = 1000 ms en pause Safari 5- non affecté non pris en charge 6 non affecté en pause 7+> = 1000 ms en pause Opera 12- non affecté non pris en charge 15+> = 1000 ms en pause
Ce que j’ai observé: sur des onglets inactifs dans Chrome , tous vos setTimeout
(doivent être identiques pour setInterval
) en attente moins que 1000ms sont arrondis à 1000ms. Je pense que les délais d'attente plus longs ne sont pas modifiés.
Cela 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 que cela se comporte de la sorte lorsque toute la fenêtre est inactive (mais cela semble assez facile à étudier).