Ich denke, dass Leistungsoptimierung für viele Entwickler von Interesse ist, da sie mehr über verschiedene Möglichkeiten zur Erledigung einer Aufgabe lernen. Eine innere Stimme fragt: „Welcher Weg ist am besten?“ Zwar gibt es viele sich ändernde Metriken für „Beste“, wie Douglas Crockfords „JavaScript: The Good Parts“ aus dem Jahr 2008, aber die Leistung ist zugänglich, weil wir sie selbst testen können.
Es ist jedoch nicht immer einfach, die Leistung richtig zu testen und nachzuweisen.
Anfang der 2000er Jahre hatte der Internet Explorer die ersten Browserkriege gewonnen. IE war eine Zeit lang sogar der Standardbrowser auf Macs. Das einst marktbeherrschende Unternehmen Netscape wurde an AOL verkauft und schließlich geschlossen. Ihr Spin-off Mozilla befand sich in einer jahrelangen Betaphase für ihren neuen eigenständigen Browser Phoenix Firebird Firefox.
Im Jahr 2003 kam Opera 7 mit Presto heraus, einer neuen, schnelleren Rendering-Engine. Außerdem veröffentlichte Apple Safari, einen leistungsorientierten Browser für Macs, der auf der wenig bekannten Konqueror-KHTML-Engine basiert. Firefox wurde 2004 offiziell eingeführt. Microsoft veröffentlichte IE 7 im Jahr 2006 und Opera 9 veröffentlichte eine schnellere JavaScript-Engine. 2007 brachte Safari sowohl für Windows als auch für das neue iPhone. 2008 gab es Google Chrome und den Android-Browser.
Mit mehr Browsern und mehr Plattformen war die Leistung ein wichtiger Teil dieser Zeit. Neue Browserversionen verkündeten regelmäßig, dass sie der neue schnellste Browser seien. Benchmarks wie Apples SunSpider und Mozillas Kraken wurden in Veröffentlichungen häufig zitiert und Google unterhielt eine eigene Octane-Testsuite. Im Jahr 2010 führte das Chrome-Team sogar eine Reihe von „Geschwindigkeitstests“ durch, um die Leistung des Browsers zu demonstrieren.
Mikroleistungstests erregten in den 2010er Jahren große Aufmerksamkeit. Das Web verlagerte sich von eingeschränkter On-Page-Interaktivität hin zu vollständig clientseitigen Single-Page-Anwendungen. Bücher wie „High Performance JavaScript“ von Nicholas Zakas aus dem Jahr 2010 haben gezeigt, wie scheinbar kleine Designentscheidungen und Codierungspraktiken erhebliche Auswirkungen auf die Leistung haben können.
Schon bald befasste sich der JavaScript-Engine-Wettbewerb mit einigen dieser zentralen Leistungsprobleme bei Hochleistungs-JavaScript, und die schnellen Änderungen bei den Engines machten es schwierig, zu wissen, was im Moment das Beste ist. Angesichts neuer Browserversionen und mobiler Geräte waren Mikroleistungstests ein heißes Thema. Im Jahr 2015 war die inzwischen geschlossene Leistungstestseite jsperf.com so beliebt, dass es aufgrund von Spam eigene Leistungsprobleme gab.
Mit der Weiterentwicklung der JavaScript-Engines war es einfach, Tests zu schreiben, aber es war schwierig sicherzustellen, dass Ihre Tests fair oder sogar gültig waren. Wenn Ihre Tests viel Speicher verbrauchen, kann es bei späteren Tests zu Verzögerungen bei der Speicherbereinigung kommen. Wurde die Rüstzeit gezählt oder von allen Tests ausgeschlossen? Erzielten die Tests überhaupt das gleiche Ergebnis? War der Kontext des Tests von Bedeutung? Wenn wir !~arr.indexOf(val) vs. arr.indexOf(val) === -1 getestet haben, machte es einen Unterschied, ob wir den Ausdruck nur ausführten oder ihn in einer if-Bedingung konsumierten?
Als die Skriptinterpreter durch verschiedene Compiler ersetzt wurden, erkannten wir einige der Vorteile – und Nebenwirkungen – von kompiliertem Code: Optimierungen. Code, der beispielsweise in einer Schleife ausgeführt wird und keine Nebenwirkungen hat, kann vollständig optimiert werden.
// Testing the speed of different comparison operators for (let i = 0; i < 10000; i += 1) { a === 10; }
Da es sich hierbei um eine 10.000-malige Ausführung eines Vorgangs ohne Ausgabe oder Nebenwirkungen handelt, könnte er bei der Optimierung vollständig verworfen werden. Es war jedoch keine Garantie.
Außerdem können sich Mikrooptimierungen von Release zu Release erheblich ändern. Die unglückliche Schließung von jsperf.com führte dazu, dass Millionen historischer Testvergleiche verschiedener Browserversionen verloren gingen, aber das können wir auch heute noch im Laufe der Zeit beobachten.
Es ist wichtig zu bedenken, dass Leistungstests der Mikrooptimierung mit vielen Vorbehalten verbunden sind.
Als die Leistungsverbesserungen nachließen, sahen wir, wie die Testergebnisse schwankten. Ein Teil davon waren Verbesserungen in den Engines, aber wir sahen auch Engines, die den Code für gängige Muster optimierten. Selbst wenn es besser codierte Lösungen gäbe, wäre es für Benutzer ein echter Vorteil, gängige Codemuster zu optimieren, anstatt zu erwarten, dass jede Website Änderungen vornimmt.
Schlimmer noch als die sich verändernde Browserleistung gab es im Jahr 2018 Änderungen an der Genauigkeit und Präzision von Timern, um spekulative Ausführungsangriffe wie Spectre und Meltdown abzuwehren. Ich habe einen separaten Artikel über diese Zeitprobleme geschrieben, falls Sie das interessiert.
Um die Sache noch komplizierter zu machen: Testen und optimieren Sie für den neuesten Browser oder den am wenigsten unterstützten Browser Ihres Projekts? Mit zunehmender Beliebtheit von Smartphones rückten auch Handheld-Geräte mit deutlich geringerer Rechenleistung in den Fokus der Überlegungen. Zu wissen, wo Sie Ihre Zeit für die besten Ergebnisse – oder wirkungsvollsten Ergebnisse – einsetzen sollten, wurde noch schwieriger.
Vorzeitige Optimierung ist die Wurzel allen Übels.
-- Donald Knuth
Dies wird häufig zitiert. Die Leute verwenden es, um zu suggerieren, dass wir, wenn wir über Optimierung nachdenken, wahrscheinlich Zeit verschwenden und unseren Code verschlechtern, um einen imaginären oder unbedeutenden Gewinn zu erzielen. Dies trifft wahrscheinlich in vielen Fällen zu. Aber hinter dem Zitat steckt noch mehr:
Wir sollten kleine Effizienzsteigerungen vergessen, sagen wir in etwa 97 % der Fälle: Eine vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir uns unsere Chancen bei diesen kritischen 3 % nicht entgehen lassen.
Das vollständigere Zitat fügt kritischen Kontext hinzu. Wir können viel Zeit in kleine Effizienzsteigerungen investieren, wenn wir uns das erlauben. Dies nimmt oft Zeit vom Ziel des Projekts ab, ohne einen großen Mehrwert zu bieten.
Ich persönlich habe viel Zeit in diese Optimierungen investiert, und im Moment schien es keine Verschwendung zu sein. Aber im Nachhinein ist nicht klar, wie viel dieser Arbeit sich gelohnt hat. Ich bin mir sicher, dass ein Teil des Codes, den ich damals geschrieben habe, die Ausführungszeit um Millisekunden verkürzt hat, aber ich kann nicht wirklich sagen, ob die eingesparte Zeit wichtig war.
Google spricht sogar von sinkenden Renditen bei der Einstellung der Octane-Testsuite im Jahr 2017. Ich empfehle dringend, diesen Beitrag zu lesen, um einen guten Einblick in die Einschränkungen und Probleme bei der Leistungsoptimierung zu erhalten, die bei Teams, die sich dieser Arbeit widmen, aufgetreten sind.
Wie können wir uns also auf diese „kritischen 3 %“ konzentrieren?
Wenn wir verstehen, wie und wann der Code verwendet wird, können wir bessere Entscheidungen darüber treffen, worauf wir uns konzentrieren müssen.
Es dauerte nicht lange, bis die Leistungssteigerungen und Variationen neuer Browser uns von dieser Art von Mikrotests abhielten und uns stattdessen auf umfassendere Tools wie Flammendiagramme konzentrierten.
Wenn Sie 30 Minuten Zeit haben, empfehle ich diese Chrome DevSummit-Präsentation 2015 über den V8-Motor. Es geht um genau diese Probleme... dass sich die Browser ständig ändern, und es kann schwierig sein, mit diesen Details Schritt zu halten.
Durch die Leistungsüberwachung und -analyse Ihrer laufenden Anwendung können Sie schnell erkennen, welche Teile Ihres Codes langsam oder häufig ausgeführt werden. Dies versetzt Sie in eine hervorragende Position, um Optimierungen in Betracht zu ziehen.
Durch die Verwendung von Tools und Bibliotheken zur Leistungsüberwachung können Sie sehen, wie der Code ausgeführt wird und welche Teile bearbeitet werden müssen. Sie geben uns auch die Möglichkeit zu sehen, ob verschiedene Bereiche auf verschiedenen Plattformen oder Browsern bearbeitet werden müssen. Möglicherweise ist localStorage auf einem Chromebook mit begrenztem Arbeitsspeicher und eMMC-Speicher viel langsamer. Möglicherweise müssen Sie mehr Informationen zwischenspeichern, um langsame oder lückenhafte Mobilfunkdienste zu bekämpfen. Wir können raten, was falsch ist, aber messen ist eine viel bessere Lösung.
Wenn Ihr Kundenstamm groß genug ist, profitieren Sie möglicherweise von RUM-Tools (Real User Monitoring), die Ihnen möglicherweise Aufschluss darüber geben, wie das tatsächliche Kundenerlebnis ist. Diese liegen außerhalb des Rahmens dieses Artikels, aber ich habe sie bei mehreren Unternehmen verwendet, um die Bandbreite der Kundenerfahrungen zu verstehen und meine Bemühungen auf die Leistung und Fehlerbehandlung in der Praxis zu konzentrieren.
Es ist einfach, sich mit der Frage „Wie kann ich dieses Ding verbessern“ zu befassen, aber das ist nicht immer die beste Antwort. Sie können viel Zeit sparen, indem Sie einen Schritt zurücktreten und fragen: „Ist das die richtige Lösung für dieses Problem?“
Probleme beim Laden einer sehr großen Liste von Elementen im DOM? Möglicherweise würde eine virtualisierte Liste, in der nur die sichtbaren Elemente auf der Seite geladen werden, das Leistungsproblem lösen.
Viele komplexe Vorgänge am Kunden durchführen? Wäre es schneller, einiges oder alles davon auf dem Server zu berechnen? Kann ein Teil der Arbeit zwischengespeichert werden?
Einen größeren Schritt zurückgehen: Ist dies die richtige Benutzeroberfläche für diese Aufgabe? Wenn Sie ein Dropdown-Menü mit zwanzig Einträgen entworfen haben und jetzt dreitausend Einträge haben, benötigen Sie möglicherweise eine andere Komponente oder Erfahrung, um eine Auswahl zu treffen.
Bei jeder Performance-Arbeit gibt es eine sekundäre Frage: „Was ist genug?“ Es gibt ein hervorragendes Video von Matt Parker von Stand-up Maths, in dem er über Code spricht, den er geschrieben hat, und wie seine Community ihn von Wochen Laufzeit auf Millisekunden verbessert hat. Obwohl es unglaublich ist, dass eine solche Optimierung möglich war, gibt es bei fast allen Projekten einen Punkt, an dem man „gut genug“ erreicht.
Für ein Programm, das nur einmal ausgeführt wird, könnten Wochen akzeptabel sein, Stunden wären besser, aber wie viel Zeit Sie dafür aufwenden, wird schnell zu einem wichtigen Gesichtspunkt.
Man könnte es sich wie Toleranzen im Ingenieurwesen vorstellen. Wir haben ein Ziel und wir haben eine Bandbreite an Akzeptanz. Wir können nach Perfektion streben und gleichzeitig verstehen, dass Erfolg und Perfektion nicht dasselbe sind.
Ziele sind ein entscheidender Teil der Optimierung. Wenn man nur weiß, dass der aktuelle Zustand schlecht ist, ist „es besser machen“ ein offenes Ziel. Ohne ein Ziel für Ihre Optimierungsreise können Sie Zeit damit verschwenden, mehr Leistung oder mehr Optimierung zu finden, obwohl Sie an etwas Wichtigerem arbeiten könnten.
Ich habe dafür keine gute Kennzahl, da die Leistungsoptimierung stark variieren kann, aber versuchen Sie, sich nicht im Unkraut zu verlieren. Hier geht es eigentlich mehr um Projektmanagement und Planung als um Codierungslösungen, aber der Input der Entwickler ist bei der Definition von Optimierungszielen wichtig. Wie im Abschnitt „Alternativen“ vorgeschlagen, lautet die Lösung möglicherweise nicht „schneller machen“.
Im Fall von Matt Parker brauchte er irgendwann die Antwort und musste das Gerät für nichts anderes verwenden. In unserer Welt messen wir häufig die Besucherleistung und ihre wahrscheinlichen finanziellen Auswirkungen im Vergleich zur Entwickler-/Teamzeit und Ihren Opportunitätskosten. Die Maßnahme ist also nicht so einfach.
Stellen wir uns vor, wir wissen, dass eine Reduzierung unserer Add-to-Cart-Zeit um 50 % unser Einkommen um 10 % steigern würde, aber es wird zwei Monate dauern, bis diese Arbeit abgeschlossen ist. Gibt es etwas, das eine größere finanzielle Auswirkung haben könnte als zwei Monate Optimierungsarbeit? Können Sie in kürzerer Zeit einen Nutzen erzielen? Auch hier geht es um Projektmanagement und nicht um Code.
Wenn Sie feststellen, dass Sie Code optimieren müssen, ist es auch ein guter Zeitpunkt zu prüfen, ob Sie diesen Code von anderen Teilen Ihres Projekts trennen können. Wenn Sie wissen, dass Sie komplexe Optimierungen schreiben müssen, die es schwierig machen, dem Code zu folgen, kann das Extrahieren in ein Dienstprogramm oder eine Bibliothek die Wiederverwendung erleichtern und es Ihnen ermöglichen, diese Optimierung an einer Stelle zu aktualisieren, wenn sie sich im Laufe der Zeit ändern muss.
Leistung ist ein kompliziertes Thema mit vielen Wendungen. Wenn Sie nicht aufpassen, können Sie viel Energie für sehr wenig praktischen Nutzen investieren. Neugier kann ein guter Lehrer sein, aber sie führt nicht immer zu Ergebnissen. Es ist von Vorteil, mit der Codeleistung herumzuspielen, bietet aber auch die Möglichkeit, die tatsächlichen Ursachen der Langsamkeit in Ihrem Projekt zu analysieren und die verfügbaren Tools zu nutzen, um sie zu beheben.
Das obige ist der detaillierte Inhalt vonJavaScript-Micro-Leistungstests, Verlauf und Einschränkungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!