Traffic wird weitergeleitet

Ein wesentlicher Aspekt von progressiven Web-Apps ist, dass sie zuverlässig sind. Sie können Assets schnell laden, das Interesse der Nutzer aufrechterhalten und sofort Feedback geben – selbst unter schlechten Netzwerkbedingungen. Wie ist das möglich? Dank des Service Worker-Ereignisses fetch.

Das Abrufereignis

Unterstützte Browser

  • 40
  • 17
  • 44
  • 11.1

Quelle

Mit dem Ereignis fetch können wir jede Netzwerkanfrage abfangen, die von der PWA im Bereich des Service Workers gestellt wurde – sowohl bei Anfragen desselben Ursprungs als auch bei ursprungsübergreifenden Anfragen. Zusätzlich zu Navigations- und Asset-Anfragen können durch den Abruf von einem installierten Service Worker Seitenaufrufe nach dem ersten Laden einer Website ohne Netzwerkaufrufe gerendert werden.

Der fetch-Handler empfängt alle Anfragen von einer App, einschließlich URLs und HTTP-Headern und lässt den App-Entwickler entscheiden, wie sie verarbeitet werden sollen.

Der Service Worker befindet sich zwischen dem Client und dem Netzwerk.

Ihr Service Worker kann eine Anfrage an das Netzwerk weiterleiten, mit einer zuvor im Cache gespeicherten Antwort antworten oder eine neue Antwort erstellen. Die Entscheidung liegt bei Ihnen. Hier ein einfaches Beispiel:

self.addEventListener("fetch", event => {
    console.log(`URL requested: ${event.request.url}`);
});

Auf eine Anfrage antworten

Wenn eine Anfrage bei Ihrem Service Worker eingeht, haben Sie zwei Möglichkeiten: Sie können sie ignorieren, sodass sie an das Netzwerk gesendet wird, oder darauf antworten. Durch das Beantworten von Anfragen innerhalb Ihres Service Workers können Sie festlegen, was ausgewählt werden soll und wie diese an Ihre PWA zurückgegeben werden, selbst wenn der Nutzer offline ist.

Um auf eine eingehende Anfrage zu antworten, rufen Sie event.respondWith() in einem fetch-Event-Handler auf. Dies sieht dann so aus:

// fetch event handler in your service worker file
self.addEventListener("fetch", event => {
    const response = .... // a response or a Promise of response
    event.respondWith(response);
});

Sie müssen respondWith() synchron aufrufen und ein Response-Objekt zurückgeben. Sie können respondWith() jedoch nicht mehr aufrufen, nachdem der Fetch-Event-Handler abgeschlossen ist, wie etwa in einem asynchronen Aufruf. Wenn Sie auf die vollständige Antwort warten müssen, können Sie ein Promise-Objekt an respondWith() übergeben, das mit einer Antwort aufgelöst wird.

Antworten erstellen

Mithilfe der Fetch API können Sie HTTP-Antworten in Ihrem JavaScript-Code erstellen. Diese Antworten können dann mithilfe der Cache Storage API im Cache gespeichert und wie von einem Webserver zurückgegeben werden.

Um eine Antwort zu erstellen, erstellen Sie ein neues Response-Objekt und legen Sie dessen Text und Optionen wie Status und Header fest:

const simpleResponse = new Response("Body of the HTTP response");

const options = {
   status: 200,
   headers: {
    'Content-type': 'text/html'
   }
};
const htmlResponse = new Response("<b>HTML</b> content", options)

Über den Cache antworten

Sie wissen nun, wie HTTP-Antworten von einem Service Worker bereitgestellt werden. Als Nächstes können Sie die Caching-Speicheroberfläche verwenden, um Assets auf dem Gerät zu speichern.

Mit der Cache Storage API können Sie prüfen, ob die von der PWA empfangene Anfrage im Cache verfügbar ist. Falls ja, können Sie damit auf respondWith() antworten. Dazu müssen Sie zuerst im Cache suchen. Mit der Funktion match(), die auf der obersten caches-Oberfläche verfügbar ist, wird in allen Geschäften in Ihrem Ursprung oder in einem einzelnen offenen Cache-Objekt gesucht.

Die Funktion match() empfängt eine HTTP-Anfrage oder eine URL als Argument und gibt ein Promise zurück, das mit der Antwort aufgelöst wird, die dem entsprechenden Schlüssel zugeordnet ist.

// Global search on all caches in the current origin
caches.match(urlOrRequest).then(response => {
   console.log(response ? response : "It's not in the cache");
});

// Cache-specific search
caches.open("pwa-assets").then(cache => {
  cache.match(urlOrRequest).then(response => {
    console.log(response ? response : "It's not in the cache");
  });
});

Caching-Strategien

Das Bereitstellen von Dateien nur aus dem Browser-Cache ist nicht für jeden Anwendungsfall geeignet. Beispielsweise kann der Cache vom Nutzer oder vom Browser entfernt werden. Deshalb sollten Sie eigene Strategien für die Bereitstellung von Assets für Ihre PWA definieren. Sie sind nicht auf eine Caching-Strategie beschränkt. Sie können für unterschiedliche URL-Muster unterschiedliche URL-Muster festlegen. Sie können beispielsweise eine Strategie für die Mindestanzahl von UI-Assets, eine weitere für API-Aufrufe und eine dritte für Bild- und Daten-URLs haben. Lesen Sie dazu event.request.url in ServiceWorkerGlobalScope.onfetch und parsen Sie die Strategie über reguläre Ausdrücke oder ein URL-Muster. Derzeit wird das URL-Muster nicht auf allen Plattformen unterstützt.

Die häufigsten Strategien sind:

Zuerst im Cache speichern
Sucht zuerst nach einer im Cache gespeicherten Antwort und greift zum Netzwerk zurück, wenn keine Antwort gefunden wird.
Netzwerk zuerst
Fragt zuerst eine Antwort vom Netzwerk. Falls keine Antwort zurückgegeben wird, wird im Cache nach einer Antwort gesucht.
Veraltet während der Neuvalidierung
Stellt eine Antwort aus dem Cache bereit, während im Hintergrund die neueste Version angefordert und für die nächste Anforderung des Assets im Cache gespeichert wird.
Nur Netzwerk
Antwortet immer mit einer Antwort vom Netzwerk oder mit einer Fehlermeldung. Der Cache wird nie konsultiert.
Nur Cache
Antwortet immer mit einer Antwort aus dem Cache oder mit einer Fehlermeldung. Das Netzwerk wird nie konsultiert. Die Assets, die mit dieser Strategie ausgeliefert werden, müssen dem Cache hinzugefügt werden, bevor sie angefordert werden.

Zuerst im Cache speichern

Mit dieser Strategie sucht der Service Worker im Cache nach der übereinstimmenden Anfrage und gibt die entsprechende Antwort zurück, sofern sie im Cache gespeichert ist. Andernfalls wird die Antwort aus dem Netzwerk abgerufen (optional wird der Cache für zukünftige Aufrufe aktualisiert). Wenn es weder eine Cache-Antwort noch eine Netzwerkantwort gibt, schlägt die Anfrage fehl. Da Assets in der Regel schneller ausgeliefert werden, wenn sie nicht an das Netzwerk gesendet werden, hat bei dieser Strategie die Leistung Vorrang vor Aktualität.

Die Strategie „Cache First“

self.addEventListener("fetch", event => {
   event.respondWith(
     caches.match(event.request)
     .then(cachedResponse => {
       // It can update the cache to serve updated content on the next request
         return cachedResponse || fetch(event.request);
     }
   )
  )
});

Netzwerk zuerst

Diese Strategie ist die Spiegelung der Strategie „Cache First“. Sie prüft, ob die Anfrage vom Netzwerk erfüllt werden kann, und versucht, sie aus dem Cache abzurufen, wenn sie nicht erfüllt werden kann. wie z. B. Cache. Wenn es weder eine Netzwerkantwort noch eine Cache-Antwort gibt, schlägt die Anfrage fehl. Die Antwort vom Netzwerk wird normalerweise langsamer abgerufen als aus dem Cache. Bei dieser Strategie werden aktualisierte Inhalte anstelle der Leistung priorisiert.

Die Strategie „Network First“

self.addEventListener("fetch", event => {
   event.respondWith(
     fetch(event.request)
     .catch(error => {
       return caches.match(event.request) ;
     })
   );
});

Bei der erneuten Validierung veraltet.

Bei der Strategie „Veraltet“ wird sofort eine im Cache gespeicherte Antwort zurückgegeben und dann das Netzwerk auf eine Aktualisierung geprüft. Falls eine solche gefunden wird, wird die im Cache gespeicherte Antwort ersetzt. Bei dieser Strategie wird immer eine Netzwerkanfrage gestellt, denn selbst wenn eine im Cache gespeicherte Ressource gefunden wird, versucht sie, den Inhalt des Cache mit den vom Netzwerk empfangenen Daten zu aktualisieren, um die aktualisierte Version in der nächsten Anfrage zu verwenden. Mit dieser Strategie können Sie also von der schnellen Bereitstellung der Strategie profitieren, die an erster Stelle im Cache steht, und den Cache im Hintergrund aktualisieren.

Veraltete Strategie bei der Neuvalidierung

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
        const networkFetch = fetch(event.request).then(response => {
          // update the cache with a clone of the network response
          const responseClone = response.clone()
          caches.open(url.searchParams.get('name')).then(cache => {
            cache.put(event.request, responseClone)
          })
          return response
        }).catch(function (reason) {
          console.error('ServiceWorker fetch failed: ', reason)
        })
        // prioritize cached response over network
        return cachedResponse || networkFetch
      }
    )
  )
})

Nur Netzwerk

Die reine Netzwerkstrategie ähnelt der Vorgehensweise von Browsern ohne Service Worker oder Cache Storage API. Anfragen geben nur dann eine Ressource zurück, wenn sie aus dem Netzwerk abgerufen werden kann. Dies ist häufig nützlich für Ressourcen wie reine Online-API-Anfragen.

Die Strategie „Nur Netzwerk“

Nur Cache

Die Nur-Cache-Strategie stellt sicher, dass Anfragen niemals an das Netzwerk gesendet werden. Alle eingehenden Anfragen werden mit einem vorab ausgefüllten Cache-Element beantwortet. Im folgenden Code wird der Event-Handler fetch mit der Methode match des Cache-Speichers verwendet, um nur auf den Cache zu reagieren:

self.addEventListener("fetch", event => {
   event.respondWith(caches.match(event.request));
});

Nur Cache-Strategie.

Benutzerdefinierte Strategien

Die oben genannten Strategien sind gängige Caching-Strategien, aber Sie sind für Ihren Service Worker und die Verarbeitung von Anfragen verantwortlich. Wenn keine dieser Funktionen für Sie geeignet ist, erstellen Sie selbst eine.

Sie können beispielsweise eine Strategie im Netzwerkbereich mit einer Zeitüberschreitung verwenden, um aktualisierte Inhalte zu priorisieren, aber nur, wenn die Antwort innerhalb eines von Ihnen festgelegten Grenzwerts erscheint. Sie können auch eine im Cache gespeicherte Antwort mit einer Netzwerkantwort zusammenführen und eine komplexe Antwort vom Service Worker erstellen.

Assets aktualisieren

Es ist nicht immer einfach, die im Cache gespeicherten Assets Ihrer PWA auf dem neuesten Stand zu halten. Die veraltete Strategie für die Neuvalidierung ist zwar eine Möglichkeit, aber nicht die einzige. Im Kapitel Aktualisieren lernen Sie verschiedene Methoden kennen, mit denen Sie die Inhalte und Assets Ihrer App auf dem neuesten Stand halten.

Ressourcen