Hintergrund: Ich mache einige Benutzeroberflächentests, bei denen festgestellt werden muss, ob die Leute aufpassen oder nicht. Bei dieser Frage geht es jedoch nicht um die API für die Sichtbarkeit von Seiten .
Insbesondere möchte ich wissen, wie mein Javascript-Code beeinflusst wird, wenn die aktuelle Registerkarte in verschiedenen Browsern nicht aktiv ist oder das Browserfenster nicht aktiv ist. Bisher habe ich Folgendes ausgegraben:
- ios 5 pausiert Javascript, wenn die Registerkarte nicht aktiv ist
setInterval
und diesetTimeout
Verzögerung wird reduziert, wenn die Registerkarten nicht aktiv sind - anscheinend erscheint dies erst seit kurzem und kann Jasmine-Komponententests unter anderem durcheinander bringen.requestAnimationFrame
wird verlangsamt, wenn der Tab nicht aktiv ist (vernünftig, ich kann mir nicht vorstellen, warum dies jemanden zu sehr betreffen würde)
Ich habe folgende Fragen:
- Unterbrechen Desktop-Browser im Gegensatz zu mobilen Browsern jemals die JS-Ausführung, wenn eine Registerkarte nicht aktiv ist? Wann und welche Browser?
- Welche Browser reduzieren die
setInterval
Wiederholung? Ist es nur auf ein Limit oder um einen Prozentsatz reduziert? Wenn ich zum Beispiel eine Wiederholung von 10 ms gegenüber einer Wiederholung von 5000 ms habe, wie wird jede davon betroffen sein? - Treten diese Änderungen auf, wenn das Fenster unscharf ist und nicht nur die Registerkarte? (Ich stelle mir vor, es wäre schwieriger zu erkennen, da die OS-API erforderlich ist.)
- Gibt es andere Effekte, die in einem aktiven Tab nicht beobachtet werden würden? Könnten sie Dinge durcheinander bringen, die sonst korrekt ausgeführt würden (dh die oben genannten Jasmin-Tests)?
javascript
browser
Andrew Mao
quelle
quelle
setInterval
/setTimeout
Zeiten unter 1000 ms in 1000 ms geändert werden, wenn die Registerkarte / das Fenster verschwommen istsetInterval
/setTimeout
times under 1000ms werden in 1000ms geändert, wenn die Registerkarte / das Fenster unscharf ist. Nicht klar, was Sie zu vermitteln versucht habenAntworten:
Test Eins
Ich habe speziell für diesen Zweck einen Test geschrieben
: Frameratenverteilung: setInterval vs requestAnimationFrame
Hinweis: Dieser Test ist sehr CPU-intensiv.
requestAnimationFrame
wird von IE 9- und Opera 12- nicht unterstützt.Der Test protokolliert die tatsächliche Zeit, die für ein nimmt
setInterval
undrequestAnimationFrame
in verschiedenen Browsern zu laufen, und gibt Ihnen die Ergebnisse in Form einer Verteilung. Sie können die Anzahl der Millisekunden ändern, umsetInterval
zu sehen, wie es unter verschiedenen Einstellungen ausgeführt wird.setTimeout
funktioniert ähnlich wie asetInterval
in Bezug auf Verzögerungen.requestAnimationFrame
Im Allgemeinen werden standardmäßig 60 fps verwendet, je nach Browser. Um zu sehen, was passiert, wenn Sie zu einer anderen Registerkarte wechseln oder ein inaktives Fenster haben, öffnen Sie einfach die Seite, wechseln Sie zu einer anderen Registerkarte und warten Sie eine Weile. Die tatsächliche Zeit, die für diese Funktionen benötigt wird, wird weiterhin auf einer inaktiven Registerkarte protokolliert.Test zwei
Eine andere Möglichkeit, dies zu testen, besteht darin, den Zeitstempel wiederholt mit
setInterval
und zu protokollierenrequestAnimationFrame
und in einer getrennten Konsole anzuzeigen. Sie können sehen, wie oft es aktualisiert wird (oder ob es jemals aktualisiert wird), wenn Sie die Registerkarte oder das Fenster inaktivieren.setInterval
requestAnimationFrame
Ergebnisse
Chrome
Chrome begrenzt das Mindestintervall
setInterval
auf etwa 1000 ms, wenn die Registerkarte inaktiv ist. Wenn das Intervall höher als 1000 ms ist, wird es im angegebenen Intervall ausgeführt. Es spielt keine Rolle, ob das Fenster unscharf ist, das Intervall ist nur begrenzt, wenn Sie zu einer anderen Registerkarte wechseln.requestAnimationFrame
wird angehalten, wenn die Registerkarte inaktiv ist.https://codereview.chromium.org/6546021/patch/1001/2001
Firefox
Ähnlich wie Chrome begrenzt Firefox das Mindestintervall
setInterval
auf etwa 1000 ms, wenn die Registerkarte (nicht das Fenster) inaktiv ist. JedochrequestAnimationFrame
läuft langsamer exponentiell , wenn die Lasche nicht aktiv ist, wobei jeder Rahmen unter 1 S, 2S, 4S, 8s und so weiter.https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296
Internet Explorer
IE begrenzt nicht die Verzögerung,
setInterval
wenn die Registerkarte inaktiv ist, sondern pausiertrequestAnimationFrame
in inaktiven Registerkarten. Es spielt keine Rolle, ob das Fenster unscharf ist oder nicht.Kante
Ab Kante 14
setInterval
wird in inaktiven Registerkarten eine Obergrenze von 1000 ms festgelegt.requestAnimationFrame
wird in inaktiven Registerkarten immer angehalten.Safari
Genau wie Chrome wird Safari
setInterval
auf 1000 ms begrenzt, wenn die Registerkarte inaktiv ist.requestAnimationFrame
wird ebenfalls angehalten.Opera
Seit der Einführung der Webkit-Engine zeigt Opera dasselbe Verhalten wie Chrome.
setInterval
ist auf 1000 ms begrenzt undrequestAnimationFrame
wird angehalten, wenn die Registerkarte inaktiv ist.Zusammenfassung
Wiederholungsintervalle für inaktive Registerkarten:
quelle
setInterval
undrequestAnimationFrame
?setInterval
und wieder aktiviert wurderequestAnimationFrame
. Ich weiß, dasssetTimeout
sichsetInterval
beide ähnlich verhalten , da beide in Firefox und Chrome das gleiche minimale Hintergrundintervall haben und in anderen Browsern keine offensichtliche Einschränkung besteht.about:config
im Browser geöffnet und derdom.min_background_timeout_value
Wert auf etwas anderes als 1000 geändert wird .requestAnimationFrame
wenn der Benutzer einfach die Anwendung wechselt (Alt + Tab außerhalb von Chrome). Solange die Registerkarte in Chrome aktiv ist, ist die "Bildrate" mehr oder weniger konstant.Was ich beobachtete: auf inaktiv Tabs in Chrome , alle
setTimeout
(muss für seinsetInterval
) wartet weniger als 1000 ms auf gerundet sind 1000 ms . Ich denke, längere Timeouts werden nicht geändert.Scheint das Verhalten seit Chrome 11 und Firefox 5.0 zu sein : https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs
Außerdem glaube ich nicht, dass es sich so verhält, wenn das gesamte Fenster inaktiv ist (aber es scheint ziemlich einfach zu untersuchen).
quelle
focus
undblur
Ereignisse scheinen sowohl Registerkarten- als auch Fensterschalter zu erkennen, sodass es möglicherweise in beide Richtungen funktionieren könnte. Aber ich frage mich, wie das Fenster erkennt, ob es tatsächlich sichtbar ist oder nicht.Eine neuere Antwort, um diese zu ergänzen: Auf Chrome 78.0.3904.108 stelle ich fest, dass all diese Zeitüberschreitungen (nicht nur die unter 1000 ms) etwas länger dauern als erwartet, wenn ich zu einem anderen Tab wechsle und dann zurückkomme. Das Verhalten, das ich sehe, wird korrekter beschrieben als "Alle Zeitüberschreitungen auf inaktiven Registerkarten können um einen zusätzlichen Betrag auf maximal 1000 ms verzögert werden." ::
quelle