Zwei Möglichkeiten für den Vorabruf: <link> Tags und HTTP-Header

Demián Renzulli
Demián Renzulli

In diesem Codelab implementieren Sie das Prefetching auf zwei Arten: mit <link rel="prefetch"> und mit dem HTTP-Link-Header.

Die Beispiel-App ist eine Website mit einer Werbe-Landingpage mit einem Sonderangebot für das meistverkaufte T-Shirt des Shops. Da die Landingpage auf ein einzelnes Produkt verweist, ist davon auszugehen, dass ein hoher Prozentsatz der Nutzer zur Produktdetailseite weitergeleitet wird. Daher eignet sich die Produktseite hervorragend für das Prefetching auf der Landingpage.

Leistung messen

Legen Sie zuerst die Baseline-Leistung fest:

  1. Klicke auf Remix zum Bearbeiten, um das Projekt bearbeitbar zu machen.
  2. Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.
  3. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  4. Klicken Sie auf den Tab Netzwerk.

  5. Wählen Sie in der Drop-down-Liste Throttling die Option Schnelles 3G aus, um eine langsame Verbindung zu simulieren.

  6. Klicken Sie in der Beispiel-App auf Jetzt kaufen, um die Produktseite zu laden.

Das Laden der Seite product-details.html dauert etwa 600 ms:

Netzwerkbereich mit Ladezeiten für „product-details.html“

Fügen Sie zur Verbesserung der Navigation ein prefetch-Tag auf der Landingpage ein, um die product-details.html-Seite vorab zu laden:

  • Fügen Sie dem Kopf der Datei views/index.html das folgende <link>-Element hinzu:
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

Das Attribut as ist optional, wird aber empfohlen. Es hilft dem Browser, die richtigen Header festzulegen und zu ermitteln, ob sich die Ressource bereits im Cache befindet. Beispiele für Werte dieses Attributs: document, script, style, font, image und andere.

So prüfen Sie, ob das Vorabladen funktioniert:

  1. Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.
  2. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  3. Klicken Sie auf den Tab Netzwerk.

  4. Wählen Sie in der Drop-down-Liste Throttling die Option Schnelles 3G aus, um eine langsame Verbindung zu simulieren.

  5. Entfernen Sie das Häkchen aus dem Kästchen „Cache deaktivieren“.

  6. Laden Sie die App neu.

Wenn die Landingpage jetzt geladen wird, wird auch die Seite product-details.html geladen, aber mit der niedrigsten Priorität:

Netzwerkbereich mit der vorab abgerufenen Datei „product-details.html“

Die Seite wird fünf Minuten lang im HTTP-Cache aufbewahrt. Danach gelten die normalen Cache-Control-Regeln für das Dokument. In diesem Fall hat product-details.html einen cache-control-Header mit dem Wert public, max-age=0. Das bedeutet, dass die Seite insgesamt fünf Minuten lang gespeichert wird.

Leistung noch einmal bewerten

  1. Laden Sie die App neu.
  2. Klicken Sie in der Beispiel-App auf Jetzt kaufen, um die Produktseite zu laden.

Sehen Sie sich den Bereich Netzwerk an. Im Vergleich zum ursprünglichen Netzwerk-Trace gibt es zwei Unterschiede:

  • In der Spalte Größe wird „Prefetch-Cache“ angezeigt. Das bedeutet, dass diese Ressource nicht aus dem Netzwerk, sondern aus dem Cache des Browsers abgerufen wurde.
  • In der Spalte Zeit sehen Sie, dass das Laden des Dokuments jetzt etwa 10 ms dauert.

Das ist eine Reduzierung um etwa 98% im Vergleich zur vorherigen Version, die etwa 600 ms in Anspruch nahm.

Netzwerkbereich mit „product-details.html“, die aus dem Prefetch-Cache abgerufen wurde

Bonuspunkte: prefetch als progressive Verbesserung verwenden

Der Vorabruf sollte am besten als progressive Verbesserung für Nutzer implementiert werden, die mit schnellen Verbindungen surfen. Mit der Network Information API können Sie die Netzwerkbedingungen prüfen und dynamisch prefetch-Tags einfügen. So können Sie den Datenverbrauch minimieren und Kosten für Nutzer mit langsamen oder teuren Datentarifen sparen.

Wenn Sie die adaptive Vorab-Datenübertragung implementieren möchten, entfernen Sie zuerst das <link rel="prefetch">-Tag aus views/index.html:

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

Fügen Sie dann public/script.js den folgenden Code hinzu, um eine Funktion zu deklarieren, die das prefetch-Tag dynamisch einfügt, wenn der Nutzer eine schnelle Verbindung hat:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

Die Funktion funktioniert so:

  • Dabei wird die Eigenschaft effectiveType der Network Information API geprüft, um festzustellen, ob der Nutzer eine 4G-Verbindung (oder schneller) nutzt.
  • Wenn diese Bedingung erfüllt ist, wird ein <link>-Tag mit prefetch als Hinweistyp generiert. Die URL, die vorab abgerufen werden soll, wird im href-Attribut übergeben. Im as-Attribut wird angegeben, dass es sich bei der Ressource um eine HTML-document handelt.
  • Schließlich wird das Script dynamisch in den head der Seite eingefügt.

Fügen Sie als Nächstes script.js zu views/index.html hinzu, direkt vor dem schließenden </body>-Tag:

<body>
      ...
      <script src="/script.js"></script>
</body>

Wenn du script.js am Ende der Seite anforderst, wird es geladen und ausgeführt, nachdem die Seite geparst und geladen wurde.

Damit das Vorabladen nicht zu Problemen mit kritischen Ressourcen für die aktuelle Seite führt, fügen Sie das folgende Code-Snippet hinzu, um injectLinkPrefetchIn4g() beim Ereignis window.load aufzurufen:

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

Auf der Landingpage wird product-details.html jetzt nur bei schnellen Verbindungen vorab abgerufen. Prüfen Sie Folgendes:

  1. Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.
  2. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  3. Klicken Sie auf den Tab Netzwerk.
  4. Wählen Sie in der Drop-down-Liste Drosselung die Option Online aus.
  5. Laden Sie die App neu.

Im Bereich „Netzwerk“ sollte product-details.html angezeigt werden:

Netzwerkbereich mit der vorab abgerufenen Datei „product-details.html“

So prüfen Sie, ob die Produktseite bei langsamen Verbindungen nicht vorab abgerufen wird:

  1. Wählen Sie in der Drop-down-Liste „Throttling“ die Option Slow 3G aus.
  2. Laden Sie die App neu.

Der Bereich Netzwerk sollte nur die Ressourcen für die Landingpage ohne product-details.html enthalten:

Im Netzwerkbereich wird angezeigt, dass „product-details.html“ nicht vorab abgerufen wird.

Mit dem HTTP-Link-Header können dieselben Ressourcen wie mit dem link-Tag vorab abgerufen werden. Ob Sie die eine oder die andere Methode verwenden, hängt hauptsächlich von Ihren Präferenzen ab, da der Leistungsunterschied unerheblich ist. In diesem Fall verwenden Sie es, um das Haupt-CSS der Produktseite vorab zu laden und so das Rendering weiter zu verbessern.

Fügen Sie in der Serverantwort für die Landingpage einen HTTP-Link-Header für style-product.css hinzu:

  1. Öffnen Sie die Datei server.js und suchen Sie nach dem get()-Handler für die Stamm-URL: /.
  2. Fügen Sie am Anfang des Handlers die folgende Zeile hinzu:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.
  2. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  3. Klicken Sie auf den Tab Netzwerk.
  4. Laden Sie die App neu.

Die style-product.css wird jetzt mit der niedrigsten Priorität vorab abgerufen, nachdem die Landingpage geladen wurde:

Im Netzwerkbereich wird angezeigt, dass „style-product.css“ vorab abgerufen wurde.

Klicken Sie auf Jetzt kaufen, um die Produktseite aufzurufen. Sehen Sie sich den Bereich Netzwerk an:

Netzwerkbereich mit der Datei „style-product.css“, die aus dem Prefetch-Cache abgerufen wurde

Die Datei style-product.css wird aus dem Prefetch-Cache abgerufen und das Laden dauert nur 12 ms.