Ich testete die Genauigkeit der setTimeout
mit diesem Test . Jetzt habe ich festgestellt, dass (wie erwartet) setTimeout
nicht sehr genau ist, aber für die meisten Geräte nicht dramatisch ungenau. Wenn ich den Test jetzt in Chrome ausführe und ihn in einer Hintergrundregisterkarte laufen lasse (also zu einer anderen Registerkarte wechseln und dort navigieren), zum Test zurückkehre und die Ergebnisse überprüfe (wenn der Test beendet ist), werden sie dramatisch geändert. Es sieht so aus, als ob die Zeitüberschreitungen viel langsamer verlaufen sind. In FF4 oder IE9 getestet, ist dies nicht aufgetreten.
Es sieht also so aus, als würde Chrome die Ausführung von Javascript in einem Tab ohne Fokus anhalten oder zumindest verlangsamen. Konnte nicht viel im Netz zu diesem Thema finden. Dies würde bedeuten, dass wir keine Hintergrundaufgaben ausführen können, wie zum Beispiel regelmäßige Überprüfungen auf einem Server mithilfe von XHR-Aufrufen und setInterval
(ich vermute, dass das gleiche Verhalten für angezeigt setInterval
wird, einen Test schreiben, wenn die Zeit für mich gekommen ist).
Hat jemand dies angetroffen? Gibt es eine Problemumgehung für diese Unterbrechung / Verlangsamung? Würden Sie es einen Fehler nennen und sollte ich es als solchen einreichen?
quelle
transition
, so dass nicht alle Divs gleichzeitig übergehen, sondern tatsächlich 15 ms nacheinander, wodurch ein rollender Effekt entsteht. Wenn ich zu einem anderen Tab gehe und nach einer Weile zurückkomme, wechseln alle Divs gleichzeitig und dassetTimeOut
wird vollständig ignoriert. Es ist kein großes Problem für mein Projekt, aber es ist eine seltsame und unerwünschte Ergänzung.Antworten:
Ich habe kürzlich danach gefragt und es ist Verhalten von Natur aus. Wenn eine Registerkarte inaktiv ist, wird die Funktion nur maximal einmal pro Sekunde aufgerufen. Hier ist die Codeänderung .
Vielleicht hilft dies: Wie kann ich festlegen, dass setInterval auch funktioniert, wenn ein Tab in Chrome inaktiv ist?
TL; DR: Verwenden Sie Web Worker .
quelle
Es gibt eine Lösung für die Verwendung von Web Workern, da diese in einem separaten Prozess ausgeführt werden und nicht verlangsamt werden
Ich habe ein winziges Skript geschrieben, das ohne Änderungen an Ihrem Code verwendet werden kann - es überschreibt einfach die Funktionen setTimeout, clearTimeout, setInterval, clearInterval
Fügen Sie es einfach vor Ihrem gesamten Code ein
http://github.com/turuslan/HackTimer
quelle
new Worker('data:text/javascript,(' + function myWorkerCode () { /*...*/ } + '()')
. Auf diese Weise können Sie auch überprüfen, ob Sie Unterstützung für Importausdrücke haben:try { eval('import("data:text/javascript,void 0")') } catch (e) { /* no support! */ }
Das Abspielen eines ~ leeren Sounds zwingt den Browser, die Leistung beizubehalten. Ich habe ihn nach dem Lesen dieses Kommentars entdeckt: Wie kann JavaScript in Chrome mit normaler Geschwindigkeit ausgeführt werden, auch wenn der Tab nicht aktiv ist?
Ich benötige eine unbegrenzte Leistung bei Bedarf für ein Browsergame, das WebSockets verwendet. Daher weiß ich aus Erfahrung, dass die Verwendung von WebSockets keine unbegrenzte Leistung gewährleistet, aber aus Tests scheint das Abspielen einer Audiodatei dies zu gewährleisten
Hier sind 2 leere Audio-Loops, die ich zu diesem Zweck erstellt habe. Sie können sie kommerziell frei verwenden: http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogg http://adventure.land/sounds/loops/empty_loop_for_js_performance.wav
(Sie enthalten -58db Rauschen, -60db funktioniert nicht)
Ich spiele sie auf Benutzerwunsch mit Howler.js: https://github.com/goldfire/howler.js
Es ist traurig, dass es keine integrierte Methode gibt, mit der die volle Javascript-Leistung standardmäßig ein- und ausgeschaltet werden kann. Crypto Miner können jedoch alle Ihre Computer-Threads mithilfe von Web Workers ohne Aufforderung entführen: |
quelle
Ich habe ein Worker-Intervall- npm-Paket veröffentlicht, das die Implementierung von Interval und ClearInterval mit Web-Workern festlegt, um auf inaktiven Registerkarten für Chrome, Firefox und IE auf dem Laufenden zu bleiben.
Die meisten modernen Browser (Chrome, Firefox und IE) und Intervalle (Fenster-Timer) werden so geklemmt, dass sie in inaktiven Registerkarten nicht öfter als einmal pro Sekunde ausgelöst werden.
Weitere Informationen finden Sie unter
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Timeouts_and_intervals
quelle
Ich habe meinen jQuery-Kern auf 1.9.1 aktualisiert und die Intervalldiskrepanz in inaktiven Registerkarten behoben. Ich würde das zuerst versuchen und dann andere Optionen zum Überschreiben von Code untersuchen.
quelle
Hier ist meine Lösung, die die aktuelle Millisekunde abruft und sie mit der Millisekunde vergleicht, in der die Funktion erstellt wurde. Für das Intervall wird die Millisekunde aktualisiert, wenn die Funktion ausgeführt wird. Sie können das Intervall / Timeout auch anhand einer ID abrufen.
quelle