JavaScript-Nutzlasten durch Codeaufteilung reduzieren

Niemand wartet gerne. Mehr als 50% der Nutzer verlassen eine Website, wenn der Ladevorgang länger als drei Sekunden dauert.

Das Senden großer JavaScript-Nutzlasten wirkt sich erheblich auf die Geschwindigkeit Ihrer Website aus. Anstatt den gesamten JavaScript-Code an Ihre Nutzer zu senden, sobald die erste Seite Ihrer Anwendung geladen wurde, teilen Sie Ihr Bundle in mehrere Teile auf und senden Sie nur das Nötigste ganz am Anfang.

Warum ist Codeaufteilung von Vorteil?

Die Codeaufteilung ist eine Technik, die darauf abzielt, die Startzeit zu minimieren. Wenn wir weniger JavaScript beim Start ausliefern, können wir Anwendungen interaktiv schneller machen, indem wir in diesem kritischen Zeitraum den Aufwand für den Hauptthread minimieren.

Im Hinblick auf Core Web Vitals trägt eine Reduzierung der beim Start heruntergeladenen JavaScript-Nutzlasten zu besseren Zeiten für First Input Delay (FID) und Interaction to Next Paint (INP) bei. Der Grund dafür ist, dass durch die Freigabe des Hauptthreads die Anwendung in der Lage ist, schneller auf Nutzereingaben zu reagieren, indem die JavaScript-Analyse-, Kompilierungs- und ausführungsbezogenen Startkosten reduziert werden.

Je nach Architektur Ihrer Website – insbesondere wenn Ihre Website stark auf clientseitiges Rendering basiert – kann die Reduzierung der Größe der für das Rendern von Markup verantwortlichen JavaScript-Nutzlasten zu kürzeren LCP-Zeiten (Largest Contentful Paint) führen. Das kann vorkommen, wenn die LCP-Ressource vom Browser verzögert gefunden wird, bis das clientseitige Markup abgeschlossen ist oder der Hauptthread zu ausgelastet ist, um dieses LCP-Element zu rendern. In beiden Fällen kann sich die LCP-Zeit für die Seite verzögern.

Messen

Lighthouse zeigt eine fehlgeschlagene Prüfung an, wenn viel Zeit für die Ausführung des gesamten JavaScript auf einer Seite benötigt wird.

Eine nicht bestandene Lighthouse-Prüfung zeigt an, dass die Ausführung der Skripts zu lange dauert.

Teilen Sie das JavaScript-Bundle auf, sodass beim Laden einer Anwendung nur der Code gesendet wird, der für die ursprüngliche Route benötigt wird. Dadurch wird die Anzahl der Skripts, die geparst und kompiliert werden müssen, minimiert, was zu kürzeren Seitenladezeiten führt.

Mit beliebten Modul-Bundler wie Webpack, Parcel und Rollup können Sie Ihre Bundles mithilfe von dynamischen Importen aufteilen. Sehen Sie sich beispielsweise das folgende Code-Snippet an, das ein Beispiel für die Methode someFunction zeigt, die beim Senden eines Formulars ausgelöst wird.

import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  // uses moduleA
}

Hier verwendet someFunction ein Modul, das aus einer bestimmten Bibliothek importiert wurde. Wenn dieses Modul nicht an anderer Stelle verwendet wird, kann der Codeblock so geändert werden, dass er über einen dynamischen Import nur dann abgerufen wird, wenn das Formular vom Nutzer gesendet wird.

form.addEventListener("submit", e => {
  e.preventDefault();
  import('library.moduleA')
    .then(module => module.default) // using the default export
    .then(() => someFunction())
    .catch(handleError());
});

const someFunction = () => {
    // uses moduleA
}

Der Code, aus dem das Modul besteht, wird nicht in das ursprüngliche Bundle aufgenommen. Er wird jetzt Lazy Loading verwendet oder dem Nutzer nur bereitgestellt, wenn er nach der Formularübermittlung benötigt wird. Wenn Sie die Seitenleistung weiter verbessern möchten, laden Sie kritische Blöcke vorab, um sie zu priorisieren und schneller abzurufen.

Obwohl das vorherige Code-Snippet ein einfaches Beispiel ist, ist Lazy Loading von Drittanbieterabhängigkeiten in größeren Anwendungen kein gängiges Muster. Normalerweise werden Abhängigkeiten von Drittanbietern in ein separates Anbieter-Bundle aufgeteilt, das im Cache gespeichert werden kann, da sie seltener aktualisiert werden. Hier finden Sie weitere Informationen dazu, wie das SplitChunksPlugin Ihnen dabei helfen kann.

Das Aufteilen auf Routen- oder Komponentenebene bei Verwendung eines clientseitigen Frameworks ist eine einfachere Methode zum Lazy Loading von verschiedenen Teilen Ihrer Anwendung. Viele beliebte Frameworks, die Webpack verwenden, bieten Abstraktionen, um Lazy Loading einfacher zu gestalten, als sich selbst mit den Konfigurationen vertraut zu machen.