Bereitstellung

Ein wichtiger Aspekt von progressiven Web-Apps ist, dass sie zuverlässig sind. können Assets schnell geladen werden. So bleiben die Nutzer interessiert und können auch bei schlechten Netzwerkbedingungen sofort Feedback geben. Wie ist das möglich? Vielen Dank für das fetch-Ereignis des Service Workers.

Das Fetch-Ereignis

Unterstützte Browser

  • Chrome: 40. <ph type="x-smartling-placeholder">
  • Edge: 17. <ph type="x-smartling-placeholder">
  • Firefox: 44. <ph type="x-smartling-placeholder">
  • Safari: 11.1 <ph type="x-smartling-placeholder">

Quelle

Mit dem Ereignis fetch können wir jede Netzwerkanfrage abfangen, die von der PWA im Bereich des Service Workers gesendet wird, und zwar sowohl für Anfragen des gleichen Ursprungs als auch für ursprungsübergreifende Anfragen. Zusätzlich zu Navigations- und Asset-Anfragen ermöglicht das Abrufen von einem installierten Service Worker, dass 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 ganz bei dir. Hier ein einfaches Beispiel:

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

Auf Anfragen reagieren

Wenn eine Anfrage bei Ihrem Service Worker eingeht, können Sie zwei Dinge tun: können Sie ihn ignorieren und dann darauf reagieren. Wenn Sie innerhalb Ihres Service Workers auf Anfragen antworten, können Sie auswählen, was an Ihre PWA zurückgegeben wird und wie diese zurückgegeben werden – auch wenn der Nutzer offline ist.

Um auf eine eingehende Anfrage zu antworten, rufen Sie event.respondWith() innerhalb eines fetch-Event-Handlers auf. Beispiel:

// 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 Abruf-Event-Handler abgeschlossen ist, wie z. B. bei einem asynchronen Aufruf. Wenn du auf die vollständige Antwort warten musst, kannst du ein Promise an respondWith() übergeben, das mit einer Antwort aufgelöst wird.

Antworten erstellen

Mit der Fetch API können Sie HTTP-Antworten in Ihrem JavaScript-Code erstellen, die mithilfe der Cache Storage API im Cache gespeichert und so zurückgegeben werden, als kämen sie von einem Webserver.

Um eine Antwort zu erstellen, erstellen Sie ein neues Response-Objekt, indem Sie seinen Text und Optionen wie Status und Header festlegen:

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)

Aus dem Cache antworten

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

Mit der Cache Storage API kannst du prüfen, ob die von der PWA empfangene Anfrage im Cache verfügbar ist. Wenn das der Fall ist, kannst du damit respondWith() antworten. Dazu müssen Sie zuerst im Cache suchen. Die Funktion match(), die auf der obersten Ebene caches verfügbar ist, durchsucht alle Geschäfte in Ihrem Ursprung oder in einem einzelnen offenen Cache-Objekt.

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

Die ausschließliche Bereitstellung von Dateien aus dem Browser-Cache ist nicht für jeden Anwendungsfall geeignet. Der Cache kann z. B. 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 Attribute definieren. 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 verwenden. Lesen Sie dazu event.request.url in ServiceWorkerGlobalScope.onfetch und parsen Sie es über reguläre Ausdrücke oder ein URL-Muster. Zum Zeitpunkt der Erstellung dieses Dokuments wird URL-Muster nicht auf allen Plattformen unterstützt.

Die gängigsten Strategien sind:

Zuerst im Cache speichern
Sucht zuerst nach einer im Cache gespeicherten Antwort und greift auf das Netzwerk zurück, wenn keine gefunden wird.
Netzwerk zuerst
Fügt zuerst eine Antwort vom Netzwerk an. Wird keine zurückgegeben, wird im Cache nach einer Antwort gesucht.
Veraltet während der Neuvalidierung
Eine Antwort wird aus dem Cache gesendet, während im Hintergrund die neueste Version angefordert und im Cache gespeichert wird, wenn das Asset das nächste Mal angefordert wird.
Nur Netzwerk
Antwortet immer mit einer Netzwerkantwort oder es kommt zu Fehlern. Der Cache wird nie abgefragt.
Nur Cache
Antwortet immer mit einer Antwort aus dem Cache oder es erfolgt eine Fehlermeldung. Das Netzwerk wird niemals konsultiert. Die Assets, die mit dieser Strategie ausgeliefert werden, müssen dem Cache hinzugefügt werden, bevor sie angefordert werden.

Zuerst im Cache speichern

Bei 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 ruft er die Antwort aus dem Netzwerk ab (optional wird der Cache für zukünftige Aufrufe aktualisiert). Wenn weder eine Cache-Antwort noch eine Netzwerkantwort vorhanden ist, wird ein Fehler ausgegeben. Da die Auslieferung von Assets ohne Aufrufen des Netzwerks tendenziell schneller geht, wird bei dieser Strategie die Leistung gegenüber der Aktualität priorisiert.

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);
     }
   )
  )
});

Zuerst Netzwerk

Diese Strategie spiegelt die Cache-First-Strategie wider. wird geprüft, ob die Anfrage vom Netzwerk ausgeführt werden kann. Ist dies nicht möglich, wird versucht, sie aus dem Cache abzurufen. Zum Beispiel Cache-First. Wenn weder eine Netzwerkantwort noch eine Cache-Antwort vorhanden ist, wird bei der Anfrage ein Fehler ausgegeben. Das Abrufen der Antwort vom Netzwerk dauert in der Regel länger als der Abruf aus dem Cache. Bei dieser Strategie werden aktualisierte Inhalte statt der Leistung priorisiert.

Die Strategie „Network First“

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

Bei Neuvalidierung abgelaufen

Bei einer veralteten Strategie zur erneuten Überprüfung wird sofort eine im Cache gespeicherte Antwort zurückgegeben und dann im Netzwerk nach einem Update gesucht. Falls eine Antwort gefunden wird, wird die im Cache gespeicherte Antwort ersetzt. Diese Strategie führt immer eine Netzwerkanfrage aus, denn selbst wenn eine im Cache gespeicherte Ressource gefunden wird, versucht sie, den Inhalt des Cache mit dem zu aktualisieren, was vom Netzwerk empfangen wurde, um die aktualisierte Version bei der nächsten Anfrage zu verwenden. Diese Strategie bietet Ihnen daher die Möglichkeit, von der schnellen Bereitstellung der Cache-Strategie zu profitieren und den Cache im Hintergrund zu aktualisieren.

Die veraltete Strategie während 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 Strategie nur für Netzwerke funktioniert ähnlich wie Browser ohne Service Worker oder die Cache Storage API. Bei Anfragen wird eine Ressource nur dann zurückgegeben, wenn sie aus dem Netzwerk abgerufen werden kann. Dies ist oft nützlich für Ressourcen wie reine Online-API-Anfragen.

Die Strategie „Nur Netzwerk“

Nur Cache

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

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

Nur-Cache-Strategie.

Benutzerdefinierte Strategien

Bei den oben genannten Caching-Strategien handelt es sich zwar um gängige Caching-Strategien, aber Sie sind für Ihren Service Worker und die Verarbeitung von Anfragen verantwortlich. Wenn keine dieser Funktionen Ihren Anforderungen entspricht, erstellen Sie eine eigene.

Sie können beispielsweise eine Netzwerkstrategie mit einem Zeitlimit 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 werden aktualisiert

Es kann eine Herausforderung sein, die im Cache gespeicherten Assets einer PWA auf dem neuesten Stand zu halten. Die veraltete Strategie während der Neuvalidierung ist eine Möglichkeit, dies zu tun, aber nicht die einzige. Im Kapitel zu Updates erfährst du, wie du die Inhalte und Assets deiner App auf dem neuesten Stand hältst.

Ressourcen