Codelab: Wichtige Assets vorab laden, um die Ladegeschwindigkeit zu verbessern

In diesem Codelab wird die Leistung der folgenden Webseite durch das Vorabladen und Vorabrufen einiger Ressourcen verbessert:

App-Screenshot

Messen

Messen Sie zuerst die Leistung der Website, bevor Sie Optimierungen vornehmen.

  • Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.

Führen Sie die Lighthouse-Leistungsprüfung (Lighthouse > Optionen > Leistung) für die Live-Version Ihres Glitch aus (siehe auch Leistungschancen mit Lighthouse erkennen).

Lighthouse zeigt für eine Ressource, die spät abgerufen wird, das folgende fehlgeschlagene Audit an:

Lighthouse: Prüfung „Wichtige Anfragen vorab laden“
  • Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  • Klicken Sie auf den Tab Netzwerk.
Netzwerkbereich mit spät entdeckter Ressource

Die Datei main.css wird nicht über ein Link-Element (<link>) abgerufen, das im HTML-Dokument platziert ist. Stattdessen wird das Link-Element nach dem window.onLoad-Ereignis über eine separate JavaScript-Datei (fetch-css.js) an das DOM angehängt. Das bedeutet, dass die Datei erst nach dem Parsen und Ausführen der JS-Datei durch den Browser abgerufen wird. Ebenso wird eine in main.css angegebene Webschriftart (K2D.woff2) erst abgerufen, wenn die CSS-Datei vollständig heruntergeladen wurde.

Die Kette kritischer Anfragen stellt die Reihenfolge der Ressourcen dar, die vom Browser priorisiert und abgerufen werden. Für diese Webseite sieht es derzeit so aus:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

Da sich die CSS-Datei auf der dritten Ebene der Anforderungskette befindet, hat Lighthouse sie als spät erkannte Ressource identifiziert.

Wichtige Ressourcen vorab laden

Die Datei main.css ist ein wichtiges Asset, das sofort nach dem Laden der Seite benötigt wird. Verwenden Sie für wichtige Dateien wie diese Ressource, die erst spät in Ihrer Anwendung abgerufen werden, ein Link-Preload-Tag, um den Browser anzuweisen, sie früher herunterzuladen. Fügen Sie dazu ein Link-Element in den Head des Dokuments ein.

Fügen Sie ein Preload-Tag für diese Anwendung hinzu:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

Mit dem Attribut as wird angegeben, welcher Ressourcentyp abgerufen wird, und mit as="style" werden Stylesheet-Dateien vorab geladen.

Laden Sie die Anwendung neu und sehen Sie sich den Bereich Network in den Entwicklertools an.

Netzwerkbereich mit vorab geladener Ressource

Der Browser ruft die CSS-Datei ab, bevor das JavaScript, das für das Abrufen zuständig ist, überhaupt vollständig geparst wurde. Beim Vorabladen wird der Browser angewiesen, die Ressource vorab abzurufen, da sie vermutlich für die Webseite wichtig ist.

Bei falscher Verwendung kann „preload“ die Leistung beeinträchtigen, da unnötige Anfragen für Ressourcen gestellt werden, die nicht verwendet werden. In dieser Anwendung ist details.css eine weitere CSS-Datei, die sich im Stammverzeichnis des Projekts befindet, aber für ein separates /details route verwendet wird. Um ein Beispiel dafür zu zeigen, wie das Vorladen falsch verwendet werden kann, fügen Sie auch einen Vorladehinweis für diese Ressource hinzu.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Laden Sie die Anwendung neu und sehen Sie sich den Bereich Network (Netzwerk) an. Es wird eine Anfrage zum Abrufen von details.css gesendet, obwohl es nicht von der Webseite verwendet wird.

Netzwerkbereich mit unnötigem Preload

Chrome zeigt im Bereich Console eine Warnung an, wenn eine vorab geladene Ressource nicht innerhalb weniger Sekunden nach dem Laden der Seite verwendet wird.

Vorabladen-Warnung in der Console

Diese Warnung kann Ihnen helfen, vorab geladene Ressourcen zu identifizieren, die nicht sofort von Ihrer Webseite verwendet werden. Sie können den unnötigen Preload-Link für diese Seite jetzt entfernen.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Eine Liste aller Ressourcentypen, die zusammen mit den richtigen Werten für das Attribut as abgerufen werden können, finden Sie im MDN-Artikel zum Vorabladen.

Zukünftige Ressourcen vorab abrufen

Prefetch ist ein weiterer Browserhinweis, mit dem eine Anfrage für ein Asset gestellt werden kann, das für einen anderen Navigationspfad verwendet wird, aber eine niedrigere Priorität als andere wichtige Assets hat, die für die aktuelle Seite benötigt werden.

Wenn Sie auf dieser Website auf das Bild klicken, werden Sie zu einer separaten details/-Route weitergeleitet.

Routendetails

Eine separate CSS-Datei, details.css, enthält alle für diese einfache Seite erforderlichen Stile. Fügen Sie index.html ein Link-Element hinzu, um diese Ressource vorab abzurufen.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

Wenn Sie nachvollziehen möchten, wie dadurch eine Anfrage für die Datei ausgelöst wird, öffnen Sie in den DevTools den Bereich Netzwerk und deaktivieren Sie die Option Cache deaktivieren.

Cache in den Chrome-Entwicklertools deaktivieren

Laden Sie die Anwendung neu. Sie werden sehen, dass eine Anfrage mit sehr niedriger Priorität für details.css gestellt wird, nachdem alle anderen Dateien abgerufen wurden.

Netzwerkbereich mit vorab abgerufener Ressource

Klicken Sie bei geöffneten Entwicklertools auf das Bild auf der Website, um zur Seite details zu gelangen. Da in details.html ein Link-Element zum Abrufen von details.css verwendet wird, wird wie erwartet eine Anfrage für die Ressource gesendet.

Netzwerkanfragen auf der Detailseite

Klicken Sie in den Entwicklertools auf die details.css-Netzwerkanfrage, um die zugehörigen Details aufzurufen. Die Datei wird aus dem Festplatten-Cache des Browsers abgerufen.

Detailsanfrage aus dem Datenträgercache abgerufen

Durch die Nutzung der Browser-Leerlaufzeit wird mit Prefetch eine frühe Anfrage für eine Ressource gestellt, die für eine andere Seite benötigt wird. Dadurch werden zukünftige Navigationsanfragen beschleunigt, da der Browser das Asset früher im Cache speichern und bei Bedarf aus dem Cache bereitstellen kann.

Vorabladen und Prefetching mit webpack

Im Beitrag JavaScript-Nutzlasten mit Codeaufteilung reduzieren wird die Verwendung dynamischer Importe zum Aufteilen eines Bundles in mehrere Chunks erläutert. Dies wird anhand einer einfachen Anwendung demonstriert, die beim Einreichen eines Formulars dynamisch ein Modul aus Lodash importiert.

Magic Sorter-App, die Code-Splitting demonstriert

Hier können Sie auf den Glitch für diese Anwendung zugreifen.

Der folgende Codeblock in src/index.js, ist dafür verantwortlich, die Methode dynamisch zu importieren, wenn auf die Schaltfläche geklickt wird.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Durch das Aufteilen eines Bundles wird die Seitenladezeit verkürzt, da die ursprüngliche Größe reduziert wird. Version 4.6.0 von webpack bietet Unterstützung für das Vorladen oder Vorabrufen von Chunks, die dynamisch importiert werden. In diesem Beispiel kann die lodash-Methode in der Leerlaufzeit des Browsers vorab abgerufen werden. Wenn ein Nutzer auf die Schaltfläche klickt, gibt es keine Verzögerung beim Abrufen der Ressource.

Verwenden Sie den spezifischen Kommentarparameter webpackPrefetch in einem dynamischen Import, um einen bestimmten Chunk vorab abzurufen. So würde es bei dieser speziellen Anwendung aussehen.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Sobald die Anwendung neu geladen wird, fügt webpack ein Prefetch-Tag für die Ressource in den Head des Dokuments ein. Das ist in DevTools im Bereich Elemente zu sehen.

Bereich „Elemente“ mit Prefetch-Tag

Wenn Sie sich die Anfragen im Bereich Netzwerk ansehen, sehen Sie auch, dass dieser Chunk mit niedriger Priorität abgerufen wird, nachdem alle anderen Ressourcen angefordert wurden.

Netzwerkbereich mit vorab abgerufener Anfrage

Obwohl Prefetch für diesen Anwendungsfall sinnvoller ist, unterstützt webpack auch das Vorladen von Chunks, die dynamisch importiert werden.

import(/* webpackPreload: true */ 'module')

Fazit

In diesem Codelab haben Sie gelernt, wie das Vorabladen oder Vorabrufen bestimmter Assets die Nutzerfreundlichkeit Ihrer Website verbessern kann. Es ist wichtig zu erwähnen, dass diese Techniken nicht für jede Ressource verwendet werden sollten. Eine falsche Verwendung kann die Leistung beeinträchtigen. Die besten Ergebnisse werden erzielt, wenn Sie nur selektiv vorab laden oder abrufen.

Zusammenfassung:

  • Verwenden Sie preload für Ressourcen, die erst spät erkannt werden, aber für die aktuelle Seite wichtig sind.
  • Verwenden Sie prefetch für Ressourcen, die für einen zukünftigen Navigationspfad oder eine zukünftige Nutzeraktion benötigt werden.

Derzeit unterstützen nicht alle Browser sowohl „preload“ als auch „prefetch“. Das bedeutet, dass nicht alle Nutzer Ihrer Anwendung Leistungsverbesserungen bemerken.

Weitere Informationen zu bestimmten Aspekten der Auswirkungen von Preloading und Prefetching auf Ihre Webseite finden Sie in den folgenden Artikeln: