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-Header Link.

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

Leistung messen

Ermitteln Sie zuerst die Baseline-Leistung:

  1. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  2. Klicken Sie auf den Tab Netzwerk.

  3. Wählen Sie in der Drop-down-Liste Drosselung die Option Schnelles 3G aus, um einen langsamen Verbindungstyp zu simulieren.

  4. 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

Um die Navigation zu verbessern, fügen Sie auf der Landingpage ein prefetch-Tag ein, um die product-details.html-Seite vorab abzurufen:

  • Fügen Sie der Datei views/index.html im Head-Bereich 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. Beispielwerte für dieses Attribut sind: document, script, style, font, image und andere.

So prüfen Sie, ob das Prefetching funktioniert:

  1. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  2. Klicken Sie auf den Tab Netzwerk.

  3. Wählen Sie in der Drop-down-Liste Drosselung die Option Schnelles 3G aus, um einen langsamen Verbindungstyp zu simulieren.

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

  5. Aktualisieren Sie die App.

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

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

Die Seite wird fünf Minuten lang im HTTP-Cache gespeichert. 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 aufbewahrt wird.

Leistung neu bewerten

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

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

  • In der Spalte Größe wird „prefetch cache“ angezeigt. Das bedeutet, dass diese Ressource aus dem Cache des Browsers und nicht aus dem Netzwerk abgerufen wurde.
  • In der Spalte Zeit sehen Sie, dass die Ladezeit des Dokuments jetzt etwa 10 ms beträgt.

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

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

Zusatzaufgabe: prefetch als progressive Verbesserung verwenden

Der Vorabruf sollte am besten als progressive Verbesserung für Nutzer mit schnellen Verbindungen implementiert werden. Mit der Network Information API können Sie die Netzwerkbedingungen prüfen und basierend darauf 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 adaptives Prefetching 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 den folgenden Code zu public/script.js 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);
    }
}

So funktioniert die Funktion:

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

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

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

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

Damit das Prefetching nicht mit wichtigen Ressourcen für die aktuelle Seite in Konflikt gerät, fügen Sie das folgende Code-Snippet hinzu, um injectLinkPrefetchIn4g() beim window.load-Ereignis aufzurufen:

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

Die Landingpage ruft product-details.html jetzt nur noch bei schnellen Verbindungen vorab ab. So überprüfen Sie das:

  1. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  2. Klicken Sie auf den Tab Netzwerk.
  3. Wählen Sie in der Drop-down-Liste Drosselung die Option Online aus.
  4. Aktualisieren Sie die App.

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

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

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

  1. Wählen Sie in der Drop-down-Liste „Drosselung“ die Option Langsame 3G-Verbindung aus.
  2. Aktualisieren Sie die App.

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-Header Link lassen sich dieselben Ressourcentypen wie mit dem link-Tag vorab abrufen. Die Entscheidung, welche der beiden Methoden Sie verwenden, hängt hauptsächlich von Ihren Vorlieben ab, da der Leistungsunterschied unbedeutend ist. In diesem Fall verwenden Sie es, um das Haupt-CSS der Produktseite vorab abzurufen und so das Rendern weiter zu verbessern.

Fügen Sie 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. Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Optionstaste + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  2. Klicken Sie auf den Tab Netzwerk.
  3. Aktualisieren Sie die App.

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:

Der Netzwerkbereich zeigt, dass „style-product.css“ aus dem Prefetch-Cache abgerufen wurde.

Die Datei style-product.css wurde aus dem Prefetch-Cache abgerufen und das Laden hat nur 12 ms gedauert.