Optimierung oder wie man sich nicht in den Fuß schießt

Guten Tag an alle. Heute möchte ich mit Ihnen über Optimierung sprechen. Was ist es, warum wird es benötigt und vor allem, wie man sicherstellt, dass es dann nicht schmerzhaft schmerzt.


Zunächst werden wir verstehen, was Optimierung im Allgemeinen ist und was Optimierung in JS ist. Optimierung ist also die Verbesserung von etwas gemäß einem quantitativen Merkmal. JS identifizierte vier quantitative Merkmale für sich:


Die Menge an Code - es ist allgemein anerkannt, dass je weniger Codezeilen geschrieben werden, desto produktiver und besser. Meine Meinung ist grundlegend anders, weil Sie durch das Schreiben einer Codezeile einen solchen Speicherverlust oder einen solchen fortwährenden Zyklus erzeugen können, dass der Browser einfach stirbt.


Geschwindigkeit (Leistung) ist die sogenannte Rechenkomplexität, dh die Anzahl der Aktionen, die der Parser ausführen muss, um den Befehl auszuführen.


Build-Geschwindigkeit - es ist kein Geheimnis, dass jetzt fast keines der Projekte auf Builder wie Webpack oder Gulp verzichten kann. Daher zeigt diese Eigenschaft die Richtigkeit der Project Builder-Einstellungen an. Glauben Sie mir, wenn der Server etwas schlauer als die Kaffeemühle ist, wird es wichtig.


Wiederverwendbarkeit von Code - Diese Eigenschaft zeigt, wie gut die Architektur für die Wiederverwendung von Funktionen, Komponenten und Modulen aufgebaut ist.
Betrachten Sie jede der Kategorien genauer, wir werden analysieren, welche Merkmale sie enthält und wovon sie abhängt.


Code Volume:

  • Überspielen. Wie viel Code des gleichen Typs wurde an verschiedenen Stellen geschrieben?
  • Kommentare Kommentare im Code sind gut, aber ich bin auf Projekte gestoßen, in denen es mehr Kommentare als Code gab.
  • Mangel an Vereinigung. Ein gutes Beispiel für ein solches Problem sind ähnliche Funktionen, die je nach Eigenschaft Nuancen aufweisen.
  • Das Vorhandensein von totem Code. Sehr oft gibt es in Projekten Debugging-Funktionen oder Funktionen, die überhaupt nicht verwendet werden.

Leistung:


  • Verwenden des Browser-Caching-Mechanismus;
  • Codeoptimierung basierend auf den Umgebungen, in denen sie ausgeführt wird;
  • Das Vorhandensein von Speicherlecks;
  • Verwenden von Web-Workern;
  • Verwenden von Verweisen auf DOM-Baumelemente;
  • Verwendung globaler Variablen;
  • Das Vorhandensein von rekursiven Aufrufen;
  • Vereinfachung mathematischer Berechnungen.

Build-Geschwindigkeit:


  • Die Anzahl der externen Abhängigkeiten;
  • Code-Konvertierungen. Dies bezieht sich auf die Anzahl der Chunks und ihre Größe, CSS-Konvertierungen, Dateikleben, Grafikoptimierung und vieles mehr.

Wiederverwendung von Code:


  • Anzahl der Komponenten;
  • Wiederholbarkeit von Bauteilen
  • Flexibilität und Anpassung.

Wie bereits in früheren Artikeln erwähnt, müssen Sie den Ausgangspunkt bestimmen und herausfinden, wie schlecht alles ist, um etwas zu ändern. Wo soll ein so umfangreicher Prozess beginnen? Beginnen Sie mit der einfachsten Sache: Beschleunigen Sie die Montage und verkürzen Sie die überschüssige Zeit des Projekts. Sie fragen, warum es sich lohnt, damit zu beginnen? Aufgrund der Tatsache, dass sie voneinander abhängig sind. Durch Reduzieren der Codemenge wird die Erstellungsgeschwindigkeit von Erstellungen erhöht und folglich Ihre Produktivität erhöht.


Die Optimierung der Build-Zeit führt uns unweigerlich in das Konzept des „kalten“ Builds ein. Dies ist der Prozess, bei dem ein Projekt von vorne beginnt und bis zu dem Punkt, an dem alle Abhängigkeiten betroffen sind und der Code vollständig neu kompiliert wird. Nicht mit Rebild verwechseln - hiermit wird Client-Code neu erstellt, ohne dass externe Abhängigkeiten und anderes Lametta aufgerufen werden.


Das Erhöhen der Build-Geschwindigkeit des Builds hilft:


  • Mit modernen Monteuren. Technologien stehen nicht still, und wenn Sie das erste Webpack haben, werden Sie beim Übergang zum vierten eine angenehme Zunahme feststellen, die bereits nichts bewirkt.
  • Alle toten Abhängigkeiten loswerden. Von Zeit zu Zeit vergessen Entwickler, die versuchen, mit Schwefelsäure die Wahrheit am Boden der Dose zu finden, nach ihren eigenen Experimenten aufzuräumen. Mein Kollege fragte einmal: „Machen Sie Abhängigkeiten, die in package.json geschrieben, aber nirgendwo im Code importiert sind, in das Paket das Bündel? " Ja, sie werden nicht in die Baugruppe selbst aufgenommen, aber das Paket wird entleert. Die Frage ist, warum?
  • Teilen Sie die Baugruppe je nach Bedarf in mehrere Profile auf. Mindestens zwei: Prod und Dev. Ein typisches Beispiel: Code-Verschleierung. Auf dem Produkt ist dies obligatorisch, da weniger Gewicht = schnelles Laden, aber auf der Entwickler verschleiert die Verschleierung nur und verbringt die Bauzeit mit unnötigen Manipulationen.
  • Parallelisierung einzelner Montageschritte;
  • Verwenden von npm-Clients, die zwischengespeichert werden können.

Um den Wiederaufbau und den "kalten" Build zu beschleunigen, müssen unnötige Kommentare und tote Codeteile herausgeschnitten werden. Was tun, wenn Sie ein großes Projekt haben und es nicht möglich ist, es selbst zu überprüfen? In solchen Fällen helfen Code-Analysatoren.


Persönlich benutze ich regelmäßig SonarQube , nicht das beste, aber flexibel. Gegebenenfalls können die Funktionen des Projekts vermittelt werden. Von Zeit zu Zeit tut er solche Dinge, die zumindest stehen, zumindest fallen, aber wie jedes Instrument muss er es benutzen können und nicht vergessen, skeptisch gegenüber seinen Bemerkungen zu sein. Trotz aller Nachteile kommt er mit der Suche nach totem Code, Kommentaren, dem Vorhandensein von Copy-Paste und kleinen Dingen wie dem Fehlen eines strengen Vergleichs zurecht.


Der Hauptunterschied zwischen SonarQube und ESlint / TSLint / Prettier und ähnlichen Unternehmen besteht darin, dass es die Qualität des Codes überprüft, das Überspielen und die Komplexität der Berechnung isoliert und Empfehlungen zu den erforderlichen Änderungen gibt. Analoge überprüfen den Code einfach auf Fehler, Syntax und Formatierung.


In der Praxis bin ich auf Codacy gestoßen , einen guten Service mit einem kostenlosen und kostenpflichtigen Abonnement. Dies ist nützlich, wenn Sie etwas an der Seite überprüfen müssen, ohne diesen "Harvester" zu Hause einsetzen zu müssen. Es verfügt über eine intuitive Benutzeroberfläche, eine detaillierte Anzeige, was mit dem Code nicht stimmt, und vieles mehr.


In diesem Artikel werde ich nicht auf das Thema des Einrichtens des Builds, der Chunks und des Restes eingehen, da alles von den Anforderungen des Projekts und des installierten Builders abhängt. Vielleicht werde ich in anderen Artikeln darüber sprechen.


Die durchgeführten Manipulationen haben dazu beigetragen, die Montage zu beschleunigen - Gewinn, aber wie geht es weiter? Da Analysatoren das Überspielen von Code finden können, ist es nützlich, ihn in separaten Modulen oder Komponenten zu platzieren, wodurch die Wiederverwendung von Code erhöht wird.


Es gab nur einen Abschnitt, den wir nicht berührt haben - die Geschwindigkeit des Codes selbst. Der Mechanismus, um ein Gefühl der Produktivität zu erzeugen, wird von allen verhassten Wortumgestaltungen genannt. Schauen wir uns genauer an, was es wert ist, beim Refactoring getan zu werden und was nicht.


Lebensregel: Wenn es funktioniert, berühren Sie es nicht, es sollte Sie nicht in diesem Prozess führen. Die erste Regel in der IT: Machen Sie ein Backup, dann werden Sie sich bedanken. Führen Sie an der Vorderseite Tests durch, bevor Sie Änderungen vornehmen, um die Funktionalität in Zukunft nicht zu verlieren. Fragen Sie sich dann, wie Sie Ladezeiten und Speicherlecks ermitteln können.


Dies wird DevTool helfen. Es wird nicht nur ein Speicherverlust angezeigt, sondern auch die Ladezeit der Seite sowie die Anzahl der Animationen angezeigt. Wenn Sie Glück haben, wird ein Audit für Sie durchgeführt. Dies ist jedoch nicht korrekt. DevTools verfügt auch über eine nette Funktion, z. B. die Begrenzung der Download-Geschwindigkeit, mit der Sie die Geschwindigkeit beim Laden von Seiten bei schlechtem Internet vorhersagen können.


Wir konnten die Probleme identifizieren, jetzt lösen wir sie!


Zunächst reduzieren wir die Ladezeit mithilfe des Browser-Caching-Mechanismus. Der Browser kann alles zwischenspeichern und anschließend dem Benutzer Daten aus dem Cache zur Verfügung stellen. Localstorage und Sessionstorage, die Ihnen niemand weggenommen hat. Mit ihnen können Sie einige der Daten speichern, die dazu beitragen, das SPA bei nachfolgenden Downloads zu beschleunigen und unnötige Serveranforderungen zu reduzieren.


Es wird als notwendig erachtet, den Code basierend auf der Umgebung, in der er ausgeführt wird, zu optimieren, aber wie die Praxis zeigt, kostet er viel Zeit und Mühe, ohne eine spürbare Steigerung zu bringen. Ich schlage vor, dies nur als Empfehlung zu betrachten.
Es ist natürlich ratsam, alle Speicherlecks zu beseitigen. Ich werde mich nicht darauf konzentrieren, ich denke, jeder weiß, wie man sie beseitigt, und wenn nicht, dann google es einfach.


Ein weiterer unserer Assistenten ist ein Webworker. Web-Worker sind Threads im Besitz eines Browsers, mit denen JS-Code ausgeführt werden kann, ohne die Ereignisschleife zu blockieren. Web-Worker können rechenintensive und langwierige Aufgaben ausführen, ohne den Benutzeroberflächenfluss zu blockieren. Wenn sie verwendet werden, werden die Berechnungen tatsächlich parallel durchgeführt. Vor uns liegt echtes Multithreading. Es gibt drei Arten von Web-Workern:


  1. Engagierte Mitarbeiter - Instanzen dedizierter Web-Mitarbeiter werden durch den Hauptprozess erstellt. Nur der Prozess selbst kann Daten mit ihnen austauschen.
  2. Shared Workers (Shared Workers) - Der Zugriff auf einen Shared Worker kann von jedem Prozess erhalten werden, der dieselbe Quelle wie der Worker hat (z. B. verschiedene Browser-Registerkarten, Iframe und andere Shared Worker).
  3. Servicemitarbeiter sind ereignisgesteuerte Mitarbeiter, die anhand ihrer Quelle und ihres Pfads registriert sind. Sie können die Webseite, mit der sie verknüpft sind, steuern, indem sie Navigationsbefehle und Ressourcenanforderungen abfangen und ändern sowie Daten zwischenspeichern, die sehr genau gesteuert werden können. All dies bietet uns hervorragende Tools, um das Verhalten der Anwendung in einer bestimmten Situation zu steuern (z. B. wenn das Netzwerk nicht verfügbar ist).

Wie man mit ihnen arbeitet, kann leicht im Internet gefunden werden.


Wir haben die Ansätze und Probleme von Drittanbietern herausgefunden. Jetzt schlage ich vor, über den Code selbst zu sprechen.


Versuchen Sie zunächst, direkte Aufrufe des DOM-Baums zu vermeiden, da dies eine zeitaufwändige Operation ist. Stellen wir uns vor, Sie manipulieren ständig ein Objekt in Ihrem Code. Anstatt mit diesem Objekt als Referenz zu arbeiten, ziehen Sie ständig den DOM-Baum, um nach diesem Element zu suchen und damit zu arbeiten, und wir implementieren das Caching-Muster im Code.


Der zweite Schritt besteht darin, globale Variablen zu entfernen. ES6 gab uns eine wunderbare Erfindung der Menschheit, die Blockvariablen genannt wird (in einfachen Worten, Variablendeklarationen von var bis let und const ).


Und schließlich das leckerste. Hier hat leider nicht jeder genug Erfahrung, um die Nuance zu verstehen. Ich bin gegen die Verwendung rekursiver Funktionen. Ja, sie reduzieren die Menge an geschriebenem Code, aber es kann nicht ohne einen Haken auskommen: Oft haben solche rekursiven Funktionen keine Beendigungsbedingungen, sie werden einfach vergessen. Wie im Sprichwort „Sie können einen Finger mit einem Hammer brechen, aber dies ist kein Hammerproblem, sondern ein Fingerbesitzer“ oder ein Witz über Katzen: Rekursive Funktionen sind nicht schlecht, Sie müssen sie kochen können.


Trotz aller Leistungsfähigkeit moderner Front-End-Anwendungen sollten Sie die Grundlagen nicht vergessen. Ein klares Beispiel für Verschwendung und Irrationalität ist das Hinzufügen neuer Elemente am Anfang des Arrays. Wer weiß, er hat verstanden, und wer nicht - jetzt werde ich es sagen. Jeder weiß, dass Array-Elemente einen eigenen Index haben. Wenn wir am Anfang ein neues Array-Element hinzufügen, sieht die Reihenfolge der Aktionen wie folgt aus:


  1. Definition der Array-Länge
  2. Nummerierung jedes Elements.
  3. Verschiebung jedes Array-Elements
  4. Fügen Sie ein neues Element in ein Array ein
  5. Array-Elemente neu indizieren.

Zusammenfassung:


Es ist Zeit abzurunden, und für diejenigen, die mit dem Format der Memos vertraut sind, führen Sie eine Liste von Schritten, dank derer Sie verstehen können, in welchem ​​Optimierungsstadium Sie sich gerade befinden und was als Nächstes zu tun ist:


  1. Wir bestimmen, wie viel alles gut / schlecht ist, entfernen die Metriken.
  2. Wir schneiden alles Unnötige aus: unbenutzte Abhängigkeiten, toter Code, unnötige Kommentare.
  3. Wir passen die Montagezeit an und beschleunigen sie, konfigurieren verschiedene Profile für die Konturen.
  4. Wir analysieren den Code und entscheiden, welche Teile wir optimieren und neu schreiben.
  5. Wir schreiben Tests, um den Verlust der Funktionalität zu verhindern.
  6. Wir beginnen mit dem Refactoring, beseitigen globale Variablen, Speicherlecks, Synchronisationscode und anderen Müll und vergessen das Caching nicht.
  7. Wir vereinfachen die Komplexität der Berechnungen und bringen alles Mögliche zum Web Worker.

Alles ist nicht so kompliziert, wie es auf den ersten Blick scheint. Ihre Sequenz wird wahrscheinlich anders sein als meine, schon allein deshalb, weil Sie Ihren eigenen Kopf auf Ihren Schultern haben. Sie werden neue Elemente hinzufügen oder umgekehrt deren Anzahl reduzieren, aber die Basis der Liste ist ähnlich. Ich habe die Aufteilung speziell beschrieben, damit diese Aktivität parallel zur Hauptarbeit ausgeführt werden kann. Oft ist der Kunde nicht bereit, für Nacharbeiten zu bezahlen, stimmt zu?


Und schließlich.


Ich glaube an dich und dass du Erfolg haben wirst. Glaubst du, ich bin naiv? Ich nehme an, Sie werden überrascht sein, aber da Sie diesen Artikel gefunden haben, lesen Sie ihn bis zum Ende. Das bedeutet (ich habe gute Nachrichten für Sie), dass Sie ein Gehirn haben und versuchen, sie zu entwickeln. Ich wünsche Ihnen viel Erfolg bei einem so schwierigen Unterfangen wie der Optimierung der Front!

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


All Articles