So verbessern Sie die Leistung von Front-End-Webanwendungen: Fünf Tipps



In vielen meiner Front-End-Projekte kam es irgendwann zu einem Rückgang der Produktivität - dies geschieht normalerweise, wenn die Komplexität der Anwendung zunimmt, und dies ist normal. Trotzdem sind die Entwickler weiterhin für die Leistung verantwortlich. In meinem Artikel werde ich fünf Tipps zur Optimierung von Anwendungen geben, die ich selbst anwende: Einige scheinen offensichtlich zu sein, andere wirken sich auf die Grundprinzipien der Programmierung aus - aber ich denke, das Aktualisieren des Speichers ist nicht überflüssig wird sein. Jeder Tipp wird durch Tests gesichert: Sie können sie selbst ausführen und die Leistung testen.

Übersetzt nach Alconost

Vorwort


Denken Sie daran: Wenn der Code nicht optimiert werden muss, gehen Sie nicht darauf ein. Natürlich sollte der Code, den Sie schreiben, schnell funktionieren, und Sie können immer einen schnelleren Algorithmus entwickeln - aber der geschriebene sollte anderen Entwicklern klar bleiben. In der Vorlesung „Programmieren als Kunst“ brachte Donald Knuth eine sehr wichtige Idee zur Codeoptimierung zum Ausdruck:

Das eigentliche Problem war, dass Programmierer zu viel Zeit damit verbrachten, sich an unangemessenen Orten und zu unangemessenen Zeiten um die Effizienz zu kümmern. Vorzeitige Optimierung ist die Wurzel aller Programmierfehler (oder zumindest der meisten).

1. Suche: anstelle von gewöhnlichen Arrays - Objekte und assoziative Arrays


Wenn Sie mit Daten arbeiten, treten häufig Situationen auf, in denen Sie beispielsweise ein Objekt suchen, etwas damit tun, dann ein anderes Objekt suchen usw. Die in JS am häufigsten verwendete Datenstruktur ist ein Array. Das Speichern von Daten in JS ist daher üblich. Wenn Sie jedoch etwas im Array suchen müssen, müssen Sie Methoden wie "find", "indexOf", "filter" verwenden oder mit Schleifen iterieren - das heißt, Sie müssen die Elemente von Anfang bis Ende durchlaufen. Daher führen wir eine lineare Suche durch, deren Komplexität 0 (n) beträgt (im schlimmsten Fall müssen wir so viele Vergleiche durchführen, wie Elemente im Array vorhanden sind). Wenn Sie diesen Vorgang einige Male auf kleinen Arrays ausführen, ist die Auswirkung auf die Leistung gering. Wenn wir jedoch viele Elemente haben und die Operation viele Male ausgeführt wird, wird die Leistung sicherlich fehlschlagen.

In diesem Fall ist es eine gute Lösung, ein reguläres Array in ein Objekt oder ein assoziatives Array zu konvertieren und eine Schlüsselsuche durchzuführen: In diesen Strukturen kann auf Elemente mit O (1) -Komplexität zugegriffen werden - wir haben einen Speicheraufruf, unabhängig von der Größe. Die Verbesserung der Arbeitsgeschwindigkeit wird durch die Verwendung einer Datenstruktur erreicht, die als Hash-Tabelle bezeichnet wird .

Sie können die Leistung hier testen: https://jsperf.com/finding-element-object-vs-map-vs-array/1 . Unten sind meine Ergebnisse:



Der Unterschied ist sehr bedeutend: Für ein assoziatives Array und ein Objekt habe ich Millionen von Operationen pro Sekunde erhalten, während für ein Array das beste Ergebnis etwas mehr als hundert Operationen sind. Natürlich wird die Datenkonvertierung hier nicht berücksichtigt, aber selbst unter Berücksichtigung ihres Betriebs wird sie viel schneller sein.

2. Anstelle von Ausnahmen - der bedingte Operator "if"


Manchmal scheint es einfacher zu sein, die Nullprüfung zu überspringen und nur die entsprechenden Ausnahmen abzufangen. Dies ist natürlich eine schlechte Angewohnheit - Sie müssen dies nicht tun. Wenn Sie einen in Ihrem Code haben, schreiben Sie einfach die entsprechenden Abschnitte neu. Um Sie jedoch vollständig zu überzeugen, werde ich diese Empfehlung mit Tests unterstützen. Ich habe mich entschlossen, drei Arten der Überprüfung zu testen: den Ausdruck „try-catch“, die Bedingung „if“ und die Berechnung des „Kurzschlusses“.

Test: https://jsperf.com/try-catch-vs-conditions/1 . Unten sind meine Ergebnisse:



Ich denke, von hier aus ist es offensichtlich, dass eine Überprüfung auf "null" erforderlich ist. Darüber hinaus gibt es, wie Sie sehen können, fast keinen Unterschied zwischen der "Wenn" -Bedingung und der Berechnung des "Kurzschlusses" - dann gilt für das, was die Seele lügt.

3. Je weniger Zyklen, desto besser


Eine weitere offensichtliche, aber vielleicht kontroverse Überlegung. Es gibt viele praktische Funktionen für Arrays: "Map", "Filter", "Reduce", sodass ihre Verwendung attraktiv aussieht und der Code mit ihnen übersichtlicher und leichter zu lesen ist. Wenn sich jedoch die Frage nach einer Verbesserung der Produktivität stellt, können Sie versuchen, die Anzahl der aufgerufenen Funktionen zu verringern. Ich entschied mich, zwei Fälle zu analysieren: 1) "Filter", dann "Map" und 2) "Filter", dann "Reduzieren" - und sie mit der Funktionskette "forEach" und der traditionellen "for" -Schleife zu vergleichen. Warum genau diese beiden Fälle? Aus den Tests wird ersichtlich, dass die erzielten Vorteile möglicherweise nicht sehr signifikant sind. Außerdem habe ich im zweiten Fall versucht, "filter" zu verwenden, wenn ich "redu" aufrufe.

Leistungstest für "Filter" und "Map": https://jsperf.com/array-function-chains-vs-single-loop-filter-map/1 . Meine Ergebnisse:



Es ist ersichtlich, dass ein Zyklus schneller ist, aber der Unterschied ist gering. Der Grund für eine so kleine Lücke ist die "Push" -Operation, die bei Verwendung der "Map" nicht erforderlich ist. Daher können Sie in diesem Fall darüber nachdenken, ob es wirklich notwendig ist, mit einem Zyklus fortzufahren.

Überprüfen wir nun "Filter" + "Reduzieren": https://jsperf.com/array-function-chains-vs-single-loop-filter-reduce/1 . Meine Ergebnisse:



Hier ist der Unterschied bereits größer: Die Kombination zweier Funktionen zu einer beschleunigte die Ausführung um fast die Hälfte. Trotzdem führt der Übergang zum traditionellen "for" -Zyklus zu einer wesentlich stärkeren Geschwindigkeitssteigerung.

4. Verwenden Sie regelmäßig for-Schleifen


Dieser Rat mag auch kontrovers erscheinen, weil Entwickler Funktionszyklen lieben: Sie sind gut gelesen und können die Arbeit vereinfachen. Sie sind jedoch weniger effektiv als herkömmliche Zyklen. Ich denke, Sie werden den Unterschied in der Verwendung von for-Schleifen vielleicht bereits bemerken, aber schauen wir uns das in einem separaten Test an: https://jsperf.com/for-loops-in-few-different-ways/ . Wie Sie sehen können, habe ich zusätzlich zu den integrierten Mechanismen auch "forEach" aus der "Lodash" -Bibliothek und "each" aus "jQuery" überprüft. Ergebnisse:



Und wieder sehen wir, dass die einfachste "for" -Schleife viel schneller ist als die anderen. Diese Schleifen eignen sich zwar nur für Arrays. Bei anderen iterierbaren Objekten sollten Sie "forEach", "for ... of" oder den Iterator selbst verwenden. "For ... in" sollte jedoch nur angewendet werden, wenn es überhaupt keine anderen Methoden gibt. Denken Sie auch daran, dass "for ... in" alle Eigenschaften des Objekts akzeptiert (und im Array sind die Eigenschaften Indizes), was zu unvorhersehbaren Ergebnissen führen kann. Überraschenderweise waren die Methoden von Lodash und jQuery in Bezug auf die Leistung nicht so schlecht, sodass Sie sie in einigen Fällen sicher anstelle des integrierten „forEach“ verwenden können (interessanterweise funktionierte die Schleife von Lodash im Test schneller als die integrierte).

5. Verwenden Sie die integrierten Funktionen, um mit dem DOM zu arbeiten


Manchmal sehen Sie sich den Code eines anderen an und stellen fest, dass der Entwickler jQuery nur zur Manipulation des DOM importiert hat. Ich bin sicher, dass Sie dies auch gesehen haben, da dies eine der beliebtesten JavaScript-Bibliotheken ist. Es ist klar, dass die Verwendung von Bibliotheken zur Steuerung des DOM nichts Falsches ist: Heute verwenden wir React und Angular, und sie tun dasselbe. Manchmal scheint es jedoch einigen, dass jQuery auch für einfache Operationen verwendet werden sollte, um ein Element aus dem DOM zu extrahieren und geringfügige Änderungen daran vorzunehmen.

Hier ist ein Vergleich der integrierten Funktionen für das DOM und ähnliche JQuery-Operationen in drei verschiedenen Fällen: https://jsperf.com/native-dom-functions-vs-jquery/1 . Meine Ergebnisse:



Auch hier erwiesen sich die grundlegendsten Funktionen - "getElementById" und "getElementsByClassName" - beim Anzeigen des DOM als die schnellsten. Bei Bezeichnern und erweiterten Selektoren ist querySelector auch schneller als jQuery. Und in nur einem Fall ist "querySelectorAll" langsamer als jQuery (Abrufen von Elementen nach Klassennamen). Weitere Informationen zum Ersetzen von jQuery finden Sie hier: http://youmightnotneedjquery.com .

Es ist klar, dass, wenn Sie die Bibliothek bereits zum Verwalten des DOM verwenden, dringend empfohlen wird, sich daran zu halten. In einfachen Fällen reichen jedoch integrierte Tools aus.

Zusätzliche Materialien


Mit diesen fünf Tipps können Sie schneller JavaScript-Code schreiben. Wenn Sie jedoch mehr über die Leistungsoptimierung erfahren möchten, finden Sie hier einige Empfehlungen:

1. Optimierung von JavaScript-Bundles mit Webpack: Dies ist ein sehr umfangreiches Thema. Wenn jedoch alles korrekt ausgeführt wird, kann das Laden von Anwendungen erheblich beschleunigt werden.

2. Datenstrukturen, grundlegende Algorithmen und ihre Komplexität: Viele glauben, dass dies „nur eine Theorie“ ist, aber im ersten Absatz haben wir gesehen, wie diese Theorie in der Praxis funktioniert.

3. Tests auf der jsPerf- Seite: Hier können Sie sich mit einem Vergleich verschiedener Möglichkeiten vertraut machen, um dieselbe Aufgabe in JavaScript auszuführen, und gleichzeitig einen wichtigen Indikator in der Praxis sehen - den Geschwindigkeitsunterschied.

Über den Übersetzer

Der Artikel wurde von Alconost übersetzt.

Alconost lokalisiert Spiele , Anwendungen und Websites in 70 Sprachen. Muttersprachliche Übersetzer, Sprachtests, Cloud-Plattform mit API, kontinuierliche Lokalisierung, Projektmanager rund um die Uhr, jedes Format von Zeichenfolgenressourcen.

Wir machen auch Werbe- und Schulungsvideos - für Websites, die verkaufen, Image, Werbung, Schulung, Teaser, Expliner, Trailer für Google Play und den App Store.

Lesen Sie mehr

Source: https://habr.com/ru/post/de456808/


All Articles