Start · Sprachen · JavaScript · Referenz · NavigationPreloadManager

NavigationPreloadManager

Schnittstelle

Verwaltet das Vorladen von Navigationsanfragen parallel zum Start eines Service Workers, damit der Worker-Start die Seitenladezeit nicht bremst.

seit JavaScript Baseline 2022: Chrome 59+, Edge 18+, Firefox 99+, Kategorie: webapi

Signatur

interface NavigationPreloadManager

Beschreibung

Wenn ein Service Worker einen fetch-Handler hat, muss der Browser bei jeder Navigation (also beim Laden einer Seite) zuerst den Worker starten, bevor die Anfrage überhaupt ins Netz geht. Das kostet je nach Gerät einige zehn bis hundert Millisekunden. Mit Navigation Preload schickt der Browser die Netzwerkanfrage schon parallel zum Start des Workers ab. Im fetch-Handler kommt man dann über event.preloadResponse an die bereits laufende Antwort.

Man erreicht die Schnittstelle über ServiceWorkerRegistration.navigationPreload. Man legt sie nicht selbst mit einem Konstruktor an. Sie hat vier Methoden, die alle ein Promise zurückgeben:

  • enable(): schaltet das Vorladen ein und gibt Promise<void> zurück.
  • disable(): schaltet das Vorladen aus und gibt Promise<void> zurück.
  • setHeaderValue(value): legt den Wert des Anfrage-Headers Service-Worker-Navigation-Preload fest (Standardwert: "true") und gibt Promise<void> zurück.
  • getState(): gibt Promise<{ enabled: boolean, headerValue: string }> zurück.

Sinnvoll ist das bei Strategien wie „Netzwerk zuerst“ oder bei Seiten, die bei jeder Navigation frisch vom Server kommen. Wenn der Service Worker Navigationen ohnehin komplett aus dem Cache bedient (App-Shell-Modell), braucht man Navigation Preload meist nicht. Die vorgeladene Antwort würde dann Bandbreite kosten, ohne genutzt zu werden.

Parameter

Name Typ Default Beschreibung
$value Pflicht string Nur für setHeaderValue(value): neuer Wert des Headers Service-Worker-Navigation-Preload. Der Server kann damit z. B. nur einen Inhaltsteil statt der ganzen Seite liefern.

Rückgabewert

Typ
NavigationPreloadManager
Beschreibung
Wird über registration.navigationPreload abgerufen. Alle Methoden sind asynchron: enable(), disable() und setHeaderValue() geben Promise<void> zurück, getState() gibt Promise<NavigationPreloadState> zurück.

Beispiele

Navigation Preload im activate-Event einschalten

// sw.js
self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    // Feature-Erkennung: nicht jeder Browser unterstützt das
    if (self.registration.navigationPreload) {
      await self.registration.navigationPreload.enable();
      console.log('Navigation Preload aktiviert');
    }
  })());
});
Navigation Preload aktiviert

Vorgeladene Antwort im fetch-Handler nutzen

// sw.js
self.addEventListener('fetch', (event) => {
  if (event.request.mode !== 'navigate') return;

  event.respondWith((async () => {
    try {
      // Antwort aus dem Vorladen (undefined, wenn deaktiviert)
      const preloaded = await event.preloadResponse;
      if (preloaded) return preloaded;

      // Fallback: normaler Netzwerkabruf
      return await fetch(event.request);
    } catch (err) {
      // Offline: Ersatzseite aus dem Cache
      const cache = await caches.open('offline-v1');
      return (await cache.match('/offline.html')) ?? Response.error();
    }
  })());
});

Header-Wert setzen und Zustand abfragen

// Im Seiten-Skript
const registration = await navigator.serviceWorker.ready;
const manager = registration.navigationPreload;

if (manager) {
  await manager.enable();
  // Server liefert bei diesem Header nur den Inhaltsbereich
  await manager.setHeaderValue('content-only');

  const state = await manager.getState();
  console.log(state);
}
{ enabled: true, headerValue: "content-only" }

// Wichtig · Fallstricke

  • Vorgeladene Antwort immer nutzen: Wenn Navigation Preload eingeschaltet ist, sollte man event.preloadResponse auch verwenden. Sonst wird dieselbe Seite doppelt geladen: einmal vom Vorladen und einmal vom eigenen fetch(). Manche Browser warnen außerdem in der Konsole, wenn die Anfrage abgebrochen wird, bevor die Antwort da ist.
  • Nur bei Navigationen: Das Vorladen betrifft nur Anfragen mit mode: 'navigate'. Unterressourcen wie Bilder, Skripte oder Stylesheets werden nicht vorgeladen.
  • Server und Caching: Der Server sollte Vary: Service-Worker-Navigation-Preload senden, wenn er abhängig vom Header unterschiedliche Inhalte liefert. Sonst können HTTP-Caches falsche Antworten ausliefern.
  • Zeitpunkt: enable() ruft man üblicherweise im activate-Event innerhalb von waitUntil() auf. Vor der Aktivierung, also ohne aktiven Worker, wird das Promise mit einem InvalidStateError abgelehnt.
  • Kompatibilität: Erst seit Firefox 99 und Safari 15.4 in allen großen Browsern verfügbar. Deshalb vorher mit if (registration.navigationPreload) prüfen, ob es unterstützt wird. Die API gibt es nur in sicheren Kontexten (HTTPS).