Optimierung von JavaScript-Assets für Seitengeschwindigkeit

Veröffentlicht: 2020-05-05

Das folgende Beispiel stammt von einer großen, komplexen Nachrichten-Website. Sie verlieren seit Jahren organischen Traffic. Ihr DOMContentLoaded Event-Timing beträgt 2615,2 MS. Sie denken vielleicht, dass ihre DOM-Größe extrem groß ist, aber nein ...

Es ist fast dasselbe wie das, was Google empfiehlt, und in diesem Dokument sind nur 1230 HTML-Knoten vorhanden.

Sie können das Timing und den Prozess Ihres domContentLoaded-Ereignisses berechnen und mithilfe von DevTools mit Ihren Mitbewerbern vergleichen.

Die Untersuchung dieses Beispiels zeigt, dass die DOM-Größe nicht unbedingt der kritische Punkt ist. Hier ist das Hauptproblem die Ressourcenreihenfolge : Die blauen Teile in „Main Tab“ sind für das HTML-Parsing. Diese Website unterbricht jedoch den Browser mit der JavaScript-Wiedergabe, bevor der HTML-Parsing-Prozess abgeschlossen ist.

(Sie können auch den Abschnitt Call Tree verwenden, um ähnliche Fehler für Ihr IT-Team zu finden.)

Dieses Beispiel zeigt deutlich, wie wichtig die Optimierung von JavaScript-Assets ist und was schief gehen kann, wenn Sie JavaScript bei Ihren Seitengeschwindigkeitsoptimierungen vernachlässigen.

Dies ist der dritte einer Reihe von vier Artikeln. Um diesen Artikel besser zu verstehen, möchten Sie vielleicht die ersten beiden Artikel der Serie lesen:

  • Javascript-Rendering und Seitengeschwindigkeit hängen eng damit zusammen, wie die Rendering-Engine eines Browsers eine Webseite erstellt.
  • Sie sollten auch erweiterte Messwerte zur Seitengeschwindigkeit verstehen, bevor Sie sich mit diesem Artikel befassen.

Ich werde einige Beispiele aus den ersten beiden Artikeln verwenden, um den Kontext in diesem Artikel darzustellen.

Was ist Javascript-Rendering und wie wirkt es sich auf Ihre Seitengeschwindigkeit aus?

Das Javascript-Rendering ist der letzte Seitenladeabschnitt, der die mit DOM und CSSOM erstellte Struktur interaktiv ändern kann. Jedes Seitenelement kann in einem vom Benutzer auslösbaren Format geändert oder normal angezeigt werden. Jedes Element mit einer display:none-Eigenschaft, auf das der Rendering-Baum nicht zugreifen konnte, kann mit JavaScript sichtbar gemacht oder über verschiedene HTML-Elemente in das DOM eingefügt werden.

JavaScript unterbricht das DOM und das CSSOM, da es das DOM und das CSSOM ändert, wenn sie vom Browser gelesen werden. Um zu verhindern, dass die Seitenladezeit und -geschwindigkeit negativ beeinflusst werden, ist es daher erforderlich, die Beziehung zwischen dem DOM-, CSSOM- und JavaScript-Rendering zu untersuchen.

Oben sehen Sie ein Beispiel für einen Rendering-Baum. Alle ineinandergreifenden Codeschnipsel in CSSOM- und HTML-Knoten haben semantische Äquivalente in der Rendering-Struktur. Wenn Sie genau hinsehen, werden Sie feststellen, dass sich der HTML-Knoten „Aktionsschaltfläche“ nicht im Rendering-Baum befindet. Der Hauptgrund dafür ist „display:none;“ CSS-Eigenschaft. Aufgrund dieses Unsichtbarkeitsbefehls wird es nicht in den Rendering-Baum aufgenommen. Um zu sehen, wie die Elemente in diesem Baum aufgebaut wurden, möchten Sie vielleicht den ersten Artikel dieser Reihe lesen.

Wenn Sie viele Seitenelemente haben, die beim ersten Laden nicht angezeigt werden, weil sie vom Benutzerverhalten abhängen, müssen Sie diese Elemente in der Reihenfolge des Ressourcenladens trennen und in die letzte Zeile einfügen. Die Verwendung eines Schatten-DOM oder eines virtuellen DOM ist an dieser Stelle die bessere Option.

Defer- und Async-Attribute für JavaScript-Ressourcen

Wenn Sie Ihre JS-Dateien in den Abschnitt einfügen und die Attribute „defer“ oder „async“ nicht verwenden, wird dies wahrscheinlich Ihre DOMContentLoaded-Zeit verzögern. Um diese Situation zu verhindern, können wir diese beiden Attribute verwenden. Defer dient dazu, den Ladevorgang einer JS-Datei zu verzögern, während 'Async' JS und andere Quellen parallel lädt. Beide haben Vor- und Nachteile. Wir werden hier nur über die wichtigsten sprechen.

  • Wenn Sie defer für eine Haupt-JS-Datei verwenden, werden Sie wahrscheinlich ihre „Initiator“-Effekte erst sehen, wenn sie installiert wird.
  • Wenn Sie zu viel Verzögerung verwenden, kann es am Ende des Ladens der Seite zu einem CPU-Engpass kommen.

Da dieser Artikel geschrieben wurde, wurde das Chrome 80-Update veröffentlicht. In der Spalte Initiator ist jetzt viel einfacher zu sehen, welche Ressource von welcher Ressource aufgerufen wird. Beispielsweise können Sie eine Bild- oder CSS-Datei sehen, die von JS aufgerufen wird. Wenn Sie mit gedrückter Umschalttaste durch die Ressourcen blättern, sehen Sie auch, welche Ressource nicht verwendet werden kann, ohne andere Ressourcen zu laden.

Scrollen bei gedrückter Umschalttaste: Die rote Farbe zeigt die bedingte Ressource für die grün markierte Ressource an.

Sie können auch den neuen Initiator-Abschnitt von Chrome für eine detailliertere Ressourcenladereihenfolge, Initiator und Prioritätsüberprüfung verwenden. Auf diese Weise können Sie extrem lange und kostspielige JS-Aufrufketten wie die folgende erkennen.

Ein Beispiel für eine lange und kostspielige JS-Aufrufkette von derselben Site. Über der ausgewählten Ressource befinden sich ihre Initiatoren. Der nächste Teil zeigt die von der ausgewählten Ressource initiierten Ressourcen.

  • Verzögerte JS-Dateien werden nach dem domInteractive-Ereignis heruntergeladen, daher müssen Sie sie entsprechend Ihren CSS-Dateien und Bildern auswählen.
  • Wenn Sie einige Benutzer-Tracker-JS-Dateien von Drittanbietern zurückstellen, können Sie möglicherweise bestimmte Benutzerverhalten nicht verfolgen.
  • Defer blockiert normalerweise nicht den DOM-Prozess, aber Async tut es. JS-Dateien mit asynchronen Attributen werden vom Browser während der HTML-Analyse und der CSSOM-Verarbeitung heruntergeladen.
  • Wenn Sie das async-Attribut zu oft verwenden, werden Sie wahrscheinlich einen CPU-Verarbeitungsengpass erzeugen und auch Ihre DOM- und CSSOM-Prozesse verlangsamen. Sie müssen sorgfältig auswählen, was verschoben oder asynchronisiert werden soll.

Hier ist ein Beispielschema für async- und defer-Attribute. Der erste wird vor domContentLoaded geladen, ohne das HTML-Parsing während des Abrufens aufzuteilen. Im zweiten Fall wird die abgerufene JS-Datei nicht ausgeführt, bevor das HTML-Parsing abgeschlossen ist.

Vorschläge und Tipps für Javascript-Rendering und -Leistung

Bevor Sie mit praktischen Beispielen beginnen, finden Sie hier einige Vorschläge zur Verbesserung der JavaScript-Renderingleistung. Dies kann auch dazu beitragen, die Seitengeschwindigkeit und die Funktionsweise eines Browsers besser zu verstehen.

Verwenden Sie keine unnötigen Variablen.

Wenn Sie SEO sind, bemerken Sie möglicherweise unnötige oder nicht verwendete Variablen in einer JavaScript-Datei. Es gibt viele Tools, die verwendet werden können, um diese Art von Fehlern zu erkennen. Nachfolgend finden Sie zwei grundlegende Beispiele für unbenutzte und unnötige Variablen.

var carName= Marke+ ” ” + Jahr;
document.getElementById(“demo”).innerHTML = carName;

Hier ist die Variable „carName“ unnötig. Sie können folgende Änderung vorschlagen:
document.getElementById(“demo”).innerHTML = Marke+ ” ” + Jahr

Oder:

[a, b, c, d, e].forEach(Funktion (Wert, Index) {
Konsole.log (Index);
});

Der Parameter „value“ ist hier nicht notwendig, da er nicht verwendet wird. Sie können es entfernen:
[a, b, c, d, e].forEach(Funktion (Index) {
Konsole.log (Index);
});

Auf der rechten Seite sehen Sie längere Verbindungszeiten (weiße Linien) und CSS- und JS-Dateien werden dank „asynchroner“ Javascripts in asymmetrischer Reihenfolge geladen.

Auf der linken Seite sind die Verbindungszeiten kürzer und CSS- und JS-Dateien werden nicht gemischt, da jede Quelle in Zeilen geladen wird. Asynchrone Attribute können Ihren Geschwindigkeitsindex reduzieren, da sie die TBT-Zeit verlängern können, daher müssen Sie eine Untersuchung durchführen und dies Ihrem Entwicklerteam für Performance-Tracker-JS-Dateien über die Registerkarte „Leistung“ melden, oder Sie können selbst einige Experimente durchführen.

Verwenden Sie Werkzeuge für schwierige Aufgaben

Für einen Programmieranfänger kann es schwierig sein, unnötige oder nicht verwendete Variablen zu finden. Möglicherweise möchten Sie einige Tools für diese Aufgaben verwenden, z. B. Chrome DevTools oder Node.js-Pakete wie Unused (Kami/node-unused: Ein Modul, das definierte, aber nicht verwendete Variablen in Ihrem Code meldet. oder für mehr nicht verwendete Variablen). Wenn Sie auch nur kleine Fehler finden, glaube ich, dass Ihr IT-Team Ihnen zuhören wird, wenn Sie Ihre JavaScript-Dateien verbessern.

Verwenden des Chrome DevTools-Abdeckungsberichts, um ungenutzten JavaScript-Code zu finden

Der Chrome DevTools Coverage Report zeigt ungenutzte JavaScript-Code-Snippets, ist aber nicht sehr praktisch. Sie denken vielleicht, dass Sie jeden roten Teil aus dem Code löschen können, aber das ist nicht der Fall… Stattdessen sollten Sie völlig ungenutzte Funktionen oder Variablen für eine große Anzahl von Kategorieseiten finden. Auf diese Weise kann Ihr Entwicklerteam davon überzeugt werden, einen TreeShaking-Prozess zu verwenden.

TreeShaking bedeutet, toten Code aus Dateien zu löschen. Ich empfehle, mit unbenutzten JS-Variablen und Funktionssuchpaketen zu lernen, um Zeit zu gewinnen.

Eine kleinere DOM-Größe hilft auch beim JavaScript-Rendering. Jeder (getElementsByTagName)-Befehl scannt Ihr DOM. Eine kleinere DOM-Größe erfordert beim Rendern von JavaScript weniger Ressourcen von Ihrem Browser und der CPU/dem Netzwerk Ihres Geräts.

Mit dem neuen Chrome 80-Update wurde auch der Abdeckungsbericht geändert. Sie haben optionale Auswahlmöglichkeiten pro Funktion und pro Block hinzugefügt. Per Block ist hier der Standardwert.

Wenn Sie „Pro Funktion“ auswählen, werden Sie einen großen Unterschied in Ihrem Bericht sehen. Der Hauptgrund für diese Situation ist, dass die Per-Function-Ansicht prüft, ob alle Funktionen verwendet werden oder nicht. Wenn 95 % der Funktion verwendet werden, definiert die Option "Pro Funktion" sie als unbenutzten Code, da 5 % des Codes nicht verwendet werden, obwohl der Großteil der Funktion verwendet wird.

Komprimieren, Minifizieren oder Uglifizieren Sie Ihre JS-Dateien.

Dies kann auf zwei Arten erfolgen. Löschen Sie zuerst die Leerzeichen und unnötigen Kommentare. Verwenden Sie zweitens verbesserte JavaScript-Operatoren für Ihre JS-Dateien und ändern Sie Namen, Variablen und Funktionen mit sofort einsatzbereiten Technologien.

Sie sollten Pfeilfunktionen für diese Art der Komprimierung kennen. Zum Beispiel anstelle dieses 84-Zeichen-Beispiels:

Funktionspfeil Islev (a, b) {
Konsole.log (a + b);
}
PfeilFonksiyon (5, 6);

Sie können es mit den Pfeilfunktionen => auf nur 50 Zeichen komprimieren
const ab = (a, b) => b + a;
console.log (ab (5, 6));

Eine andere Methode zum Kürzen/Komprimieren gilt für If-Anweisungen. Anstelle dieses Codeschnipsels mit 63 Zeichen:
wenn (a<b) {
Konsole.log(ab);
}
anders {
Konsole.log(a+b);

Sie können den folgenden mit 43 Zeichen verwenden:
(a<b) ? Konsole.log(ab) : Konsole.log(a+b);

Sie können Ihrem IT-Team auch vorschlagen, die Zeichen $ und _ für die Komprimierung zu verwenden. Die meisten JavaScript-Dateien funktionieren für die Neuinterpretation von DOM. Dazu sehen Sie möglicherweise viele document.getElementById(x); Codeschnipsel in Dateien. Sie können für diese Aufgabe ein $-Zeichen verwenden. Dies erspart Ihnen einen riesigen Haufen nutzloser Größe.

Die meisten JavaScript-Bibliotheken verwenden standardmäßig $ für die Funktionsdefinition, aber nicht alle, da $ auch ein Buchstabe ist.

In dieser Situation können Sie vorschlagen, dass Ihr IT-Team Folgendes verwendet:
Funktion $(x) {return document.getElementById(x);} .

Verwenden Sie einen geeigneten Rendering-Typ

JavaScript- und Webseiten-Rendering-Typen in Bezug auf die SEO-Kompatibilität.
SSR Hydration bedeutet, dass einige der JS-Komponenten mit Client Side Rendering gerendert werden. Es ist nützlich für FP und FMP, aber es kann einige Nachteile für TTI- und Geschwindigkeitsindex-Scores geben.
Bildquelle: Notprovided.eu

Best Practices für die Codierung der JavaScript-Renderingleistung

  • Ein weiterer wichtiger Komprimierungsbeitrag ergibt sich aus der Verwendung von „_“. Sie können „underscore.js“ für verbesserte JavaScript-Schreibformate und -Funktionen verwenden. Auf diese Weise erstellen Sie kleinere JS-Dateien, während Sie Listen und Sammlungen mit kürzeren JS-Funktionen ohne integrierte JS-Funktionen manipulieren.
  • Die Verwendung vieler langer und anstrengender Variablenänderungen und die Verschmutzung globaler Variablen sind ebenfalls Quellen für langsames Rendern. Sie sollten die allgemeinen Gültigkeitsbereichsoptionen Ihrer Funktionen und die globalen Variablen-/Long-Variablentypen festlegen. Die Verwendung lokaler Variablen mit 'Let' ist besser für das Rendern. Wegen lokaler Variablen prüfen Browser andere globale Funktionsvariablen nicht auf die nächste Änderung.

Um eine realistischere Leistungsprüfung zu simulieren, was Sie beispielsweise auf Low-End-Mobiltelefonen sehen könnten, sollten Sie die Einstellungen CPU-Drosselung und schnelle/langsame 3G-Verbindung in Chrome DevTools verwenden.
Bildquelle: Addy Osmani

  • Die Verwendung kleinerer JS-Funktionen und Variablenketten verbessert Ihre Renderleistung. Außerdem ist es besser, den Selektor „this“ anstelle des Selektors „with“ zu verwenden. „Dieser“ Selektor in Javascript ist im Gegensatz zu „with“ ein lokal funktionierender Code, die gleiche Logik mit let und var gilt auch hier.
  • Wenn Sie Ihre Anweisungen in For-Schleifen-Codeschnipseln verwenden, wird dies auch Ihre Rendering-Geschwindigkeit ein wenig verlangsamen. Weil Ihre Funktionsanweisung durch jedes Element der Schleife iteriert. Sie können einfach eine neue Variable für Schleifenelemente erstellen und diese Elemente mit einer Funktion außerhalb der For-Schleife aufrufen.
  • Wenn Sie ein HTML-Element mehrfach erreichen möchten, können Sie dafür eine Variable anlegen und diese mit den gewünschten Funktionen aufrufen. Das Erreichen eines HTML-Elements mit JavaScript ist kein schneller Prozess. Sie könnten Ihren Browser einfach mehr belasten.

Eine weitere Möglichkeit zur Verbesserung der Javascript-Rendering-Leistung ist das trisomorphe Rendering über Service Worker. Sie können einige Ihrer JS-Dateien für zukünftige Sitzungen in den Browserspeicher des Clients stellen. Auf diese Weise können Sie Ihre Website offline arbeiten lassen.
Eine einfache Demo zum besseren Verständnis und zum Üben mit Servicemitarbeitern finden Sie hier

Anknüpfen: Wie sich die Optimierung von JavaScript und Seitengeschwindigkeit auf SEO auswirkt

Um zu verhindern, dass JavaScript-Assets Ihre Seitengeschwindigkeit sabotieren, haben wir gesehen, wie Defer und Async einen großen Unterschied machen können. Wir haben uns auch einige der „Debugging“-Strategien und Codierungstipps angesehen, die Ihnen helfen können, die Geschwindigkeit Ihrer Seiten mit JavaScript-Assets zu verbessern.

Nachdem wir nun gesehen haben, wie Browser Webseiten erstellen, wie die Seitengeschwindigkeit gemessen und beeinflusst wird und welche Rolle die Optimierung von JavaScript bei der Seitenladezeit spielt, wird der nächste Artikel zeigen, wie sich die Reihenfolge beim Laden von Ressourcen auf die Seitengeschwindigkeit und das Crawl-Budget auswirkt.

Wenn Sie daran interessiert sind, die vorherigen Artikel in dieser Serie von vier Artikeln zu lesen, finden Sie sie hier:

  • „Wie erstellt ein Browser eine Webseite“
  • „Erweiterte Seitengeschwindigkeitsmetriken“.
Starten Sie Ihre kostenlose Testversion