Ich habe eine Seite, auf der ich einen Countdown-Timer laufen lassen muss, um den Leuten zu zeigen, wie viel Zeit sie noch haben, um eine Aktion abzuschließen.
Dieser Timer wird Tage lang laufen und wahrscheinlich nur MomentJS verwenden, um etwas wie "in 4 Tagen" aus der Funktion to()
von MomentJS zu sagen.
Wenn wir noch eine Stunde Zeit haben, werde ich zu einem Countdown nach Minuten wechseln, und wenn die Minuten niedrig genug sind, werde ich einen Sekundentimer haben. Wenn wir zu den letzten paar Minuten kommen, werde ich sogar Millisekunden anzeigen.
So ziemlich gibt es zwei Haupttechniken, um den Countdown-Timer zu animieren.
setInterval()
requestAnimationFrame()
Nun, ich habe gleich bemerkt, dass die requestAnimationFrame()
-Methode viel flüssiger für das Auge ist, es funktioniert großartig - besonders wenn ich Millisekunden zeige. Es dauerte jedoch nicht lange, bis ich bemerkte, dass mein armer Computer ein wenig warm wurde. All diese "Animation" verursacht eine ziemlich große Belastung für meine CPU. Ich habe versucht, CPU-Monitore zu verwenden, und habe mich nach Wegen umgesehen, um zu sehen, wie viel diese Belastung auf meine CPU wirkt, aber insgesamt kann ich kein Tool finden, das mir eine klare Grafik zeigt, welche Art von CPU-Last mein kleiner Countdown-Timer ist verwenden.
Also habe ich beschlossen, einen Weg zu finden, den FPS zu begrenzen und zu sehen, ob das mein Problem reduzieren würde. Und ja, tut es. Wenn Sie setTimeout()
zusammen mit requestAnimationFrame()
verwenden, können Sie eine Wartezeit festlegen, bevor Sie Ihre nächste Funktion aufrufen.
Was die Frage aufwirft, wenn Sie setTimeout()
verwenden - Warum benutzen Sie nicht einfach setInterval()
und vergessen die zusätzliche Optimierung, die Ihnen requestAnimationFrame()
bietet?
Ich habe mich etwas umgeschaut und eine andere Methode gefunden, die einfach überprüft, ob die richtige Menge an Intervallzeit seit dem letzten Aufruf von requestAnimationFrame()
vergangen ist. Ich habe einige Optimierungen vorgenommen, wie dieser Code funktioniert und endete mit einer der beiden Funktionen, die ich unten messen möchte.
Am Ende möchte ich einen eindeutigeren Weg haben, dies zu messen - denn der Aktivitätsmonitor auf meinem Mac ist kaum ein zuverlässiges Werkzeug, um genau zu lesen - und ich finde keinen Weg, um genau zu messen der Code, den ich verwende.
Chrome hat einige weitere Werkzeuge, den Profiler und die Zeitleiste - die beide sehr hilfreich sind, aber sie geben mir nicht die Metrik, nach der ich suche - CPU-Last.
Hier sind vier Code-Snippets, die genau dasselbe tun - alle benutzen:
Der Code ist 100% identisch, der einzige Unterschied ist, wie ich den FPS der Animation begrenze.
Ich würde gerne einen Weg finden, um den Unterschied zwischen den vier Funktionen bei der CPU-Last so genau wie möglich zu messen. Und dann würde ich gerne den FPS ändern, um zu sehen, ob ich eine akzeptable Last für meine Anwendung finde und dann kann ich den Sweet Spot finden - die richtige Menge an FPS während der verschiedenen Timer-Phasen.
Technik 1 - setTimeout ()
Technik 2 - Delta zwischen den Intervallen
Technik 3 - setInterval ()
Es wäre auch interessant, eine völlig ungedrosselte Version wie folgt zu sehen:
Technik 4 - Kein Gas
Einfach ausgedrückt: Wie misst man den CPU-Lastunterschied zwischen vier ähnlichen JavaScript-Funktionen?
Weiß jemand schon, welcher von diesen mehr performant sein wird? (Ich weiß, das ist nicht wirklich ein Wort)
Offensichtlich
setInterval()
ist die schlechteste Lösung. WeilsetInterval()
immer noch läuft, während Sie nicht auf der Registerkarte sind, verschwenden CPU und damit Akkulaufzeit.
Offensichtlich ist die Berechnungsmethode
Delta Interval Math
die einfachste und genaueste Methode zur Berechnung der Intervallzeit. Wenn Sie diesen Algorithmus mit der Genauigkeit der Berechnung von Rahmenzeiten mitperformance.now()
kombinieren, können Sie Ergebnisse genau in Mikrosekunden mit Ihren Animationsrahmen erzielen.(und ja, auch
requestAnimationFrame()
verwendetperformance.now()
time als erstes Argument, das an die Callback-Funktion übergeben wird) .Und ja Leute, ich meine wirklich Mikrosekunden. Das ist 1s / 1000ms / 1000μs.
Mach weiter, teste es jetzt. Öffne deine Konsole und tippe:
performance.now()
Und du bekommst eine Zahl, die aussieht wie2132438.165
- das sind Millisekunden, seit der Browser den ersten Frame gerendert hat.(Das ist besonders cool, weil μ ein griechisches Zeichen
+10 nerd points
ist)
Kombinieren Sie
requestAnimationFrame()
(wodurch Ihre Animation beim Wechseln zwischen Tabs in den Ruhezustand versetzt wird) mitsetTimeout()
, wodurch der FPS Ihrer Animation auf ein beliebiges Millisekundenintervall gedrosselt werden kann.Beachten Sie jedoch, dass der Unterschied zwischen dieser Methode und der
Delta Interval Math
-Methode sehr leicht unterschiedlich ist. Ich habe nicht einmal eine Möglichkeit zu quantifizieren, wie klein der Unterschied ist. Von dem, was ich sagen kann, könnte es ein Viertel bis ein Achtel effizienter sein. Aber du verlierst eine Menge Glätte dafür. Ihre Wahl.
Ich freue mich immer noch auf eine bessere Möglichkeit, dies zu tun, vielleicht auf eine Weise, die es mir erlaubt, Daten zwischen verschiedenen Funktionen zu vergleichen.
Bis dahin konnte ich diese Bilder mithilfe von Google's Javascript erstellen CPU-Profiler
Auflistung in der Reihenfolge, in der ich glaube, dass sie performant sind, aber mit Titeln, die der ursprünglichen Frage entsprechen:
Technik 2 - Delta zwischen den Intervallen
Nun, nach dem Aussehen würde ich die verschiedenen Funktionen in dieser Reihenfolge der Leistung ordnen:
setInterval()
function. setTimeout() wrapping the
requestAnimationFrame () 'call. requestAnimationFrame()
aufgerufen wird
requestAnimationFrame()
durchlaufen
Die setInterval()
-Funktion ist besser als jedes requestAnimationFrame()
-Muster, das ich zumindest für CPU-Nutzungsgründe gefunden habe NUR WÄHREND SIE AUF DEM TAB sind.
Wenn also CPU-Kosten oder requestAnimationFrame()
und drosseln Sie den FPS mit:
setTimeout()
-Methode, die ein wenig weniger für die CPU funktioniert (das Beste aus beiden Welten) - aber zugegebenermaßen weniger flüssig als die Methode unten. Delta Interval Math
, die eine Animation etwas glatter erscheinen lässt (Und die Technik-Umrisse in dieser Frage / Antwort mit der Zeit von performance.now()
und der Zeit, die von requestAnimationFrame()
gemeldet wird, verwendet das aktuelle performance.now()
, das im ersten Argument der Callback-Funktion bereitgestellt wird. Weil wir den genauesten Algorithmus verwenden, den ich gesehen habe, um den Animationsrahmen zu berechnen (Sie berechnen tatsächlich bis auf eine Millionstel Sekunde oder a Mikrosekunden 1s / 1000ms / 1000μs) Es gibt keinen RIESIGEN Unterschied in der CPU-Last von dieser Technik und setTimeout()
- aber es gibt einen Unterschied (siehe die beigefügten Bilder) Warum ist requestAnimationFrame()
die Bombendigitalität? - Denn: Wenn Sie nicht auf dieser Registerkarte sind, wird sie vom Browser deaktiviert Deine Animationen warten darauf, dass du zurückkommst. UND mit performance.now () erreichst du Mikrosekunden (μs) Genauigkeit in deiner Animation.
Es wird gesagt, dass requestAnimationFrame()
eine" optimierte "Methode ist, um sicherzustellen, dass Ihre Animation zusammen mit anderen Browsern funktioniert, so dass Ihre Animation" passt "mit dem, was der Browser macht, kommt es auch bei einem 60FPS Callback Kosten.
about:blank
Tab geöffnet. start
auf Googles Javascript CPU Profiler und genau 10 Sekunden später habe ich auf stop
geklickt (ich habe ein spezielles Klick-Makro in meinem Gamer-Maus spezielle Treiber-Software , die ziemlich gut funktioniert - Sobald ich auf den Knopf klicke Es klickt start
und 10 Sekunden später ein weiterer Klick auf stop
- gut genug für diese Fotos) about:blank
geladen. [shift] + [cmd] + [4]
und dann drückst du space
auf der Tastatur, um den Screenshot genau um das Fenster zu legen. Ich habe immer noch keine Möglichkeit zu sehen, wie der CPU-Verbrauch ist. Diese Grafik lässt mich etwas detaillierter sehen. Die anderen Google Javascript CPU Profiler -Bildschirme sind ebenfalls etwas vage in diesem Sinne. Vielleicht weiß ich einfach nicht, wie man das Werkzeug benutzt.
Wenn jemand einen besseren Benchmark für das Testen weiß, bitte senden Sie eine Antwort und ich werde es überprüfen. Ich hoffe es ist besser als dieses Durcheinander. Und danke im Voraus.
Das Hauptproblem besteht darin, harte Daten von einem CPU-Profil zu einem anderen zu quantifizieren und zu vergleichen. Das ist es, was ich am meisten vermisse.
Tags und Links javascript performance requestanimationframe settimeout setinterval