Unterstützung von Offline- und Netzwerkkonnektivität in Progressive Web Apps

Viele Jahre lang waren Organisationen nicht bereit, über systemeigene Software stark in webbasierte Software zu investieren, da Webanwendungen von stabilen Netzwerkverbindungen abhängig waren. Heute bietet die Plattform für progressive Web Apps (PWA) stabile Optionen, mit denen Benutzer weiterhin arbeiten können, auch wenn die Netzwerkverbindung instabil wird oder offline geht.

Verwenden der Zwischenspeicherung zur Verbesserung PWA Leistung

Mit der Einführung von Service Workernhat die Webplattform die Cache API hinzugefügt, um zugriff auf verwaltete zwischengespeicherte Ressourcen bereitzustellen. Diese zusagebasierte API ermöglicht Entwicklern das Speichern und Abrufen vieler Webressourcen – HTML, CSS, JavaScript, Bilder, JSON usw. In der Regel wird die Cache-API im Kontext eines Service Worker verwendet, ist aber auch im Hauptthread des window Objekts verfügbar.

Eine häufige Verwendung für die Cache API ist das Vorabspeichern wichtiger Ressourcen, wenn ein Service Worker installiert wird, wie im folgenden Code dargestellt.

self.addEventListener( "install", function( event ){
    event.waitUntil(
        caches.open( "static-cache" )
              .then(function( cache ){
            return cache.addAll([
                "/css/main.css",
                "/js/main.js",
                "/img/favicon.png",
                "/offline/"
            ]);
        })
    );
});

Der obige Code wird während des Lebenszyklusereignisses für Service Worker ausgeführt install und öffnet einen Cache mit dem Namen static-cache . Wenn ein Zeiger auf den Cache vorhanden ist, werden dem Cache mithilfe der Methode vier Ressourcen addAll() hinzugefügt.

Der oben beschriebene Ansatz ist häufig mit dem Cacheabruf während eines fetch Ereignisses gekoppelt, wie folgt:

self.addEventListener( "fetch", event => {
    const request = event.request;
    const url = request.url;

    // If we are requesting an HTML page.
    if ( request.headers.get("Accept").includes("text/html") ) {
        event.respondWith(
            // Check the cache first to see if the asset exists, and if it does, 
            // return the cached asset.
            caches.match( request )
                  .then( cached_result => {
                if ( cached_result ) {
                    return cached_result;
                }
                // If the asset isn't in the cache, fall back to a network request 
                // for the asset, and proceed to cache the result.
                return fetch( request )
                       .then( response => {
                    const copy = response.clone();
                    // Wait until the response we received is added to the cache.
                    event.waitUntil(
                        caches.open( "pages" )
                              .then( cache => {
                            return cache.put( request, response );
                        });
                    );
                    return response;
                })
                // If the network is unavailable to make a request, pull the offline
                // page out of the cache.
                .catch(() => caches.match( "/offline/" ));
            })
        ); // end respondWith
    } // end if HTML
});

Der obige Code wird innerhalb des Service Worker ausgeführt, wenn der Browser eine fetch Anforderung für diese Website sendet. Innerhalb dieses Ereignisses gibt es eine bedingte Anweisung, die ausgeführt wird, wenn die Anforderung für eine HTML-Datei gilt. Der Service Worker überprüft mithilfe der Methode, ob die Datei bereits in einem Cache vorhanden match() ist:

  • Wenn die Anforderung im Cache vorhanden ist, wird dieses zwischengespeicherte Ergebnis zurückgegeben.
  • Wenn die Anforderung nicht im Cache vorhanden ist, wird eine neue fetch für diese Ressource ausgeführt, eine Kopie der Antwort für später zwischengespeichert, und die Antwort wird zurückgegeben.
    • Wenn der fetch Fehler auftritt, weil das Netzwerk nicht verfügbar ist, wird die Offlineseite aus dem Cache zurückgegeben.

Diese einfache Einführung zeigt, wie Sie die Zwischenspeicherung in Ihrer progressiven Web-App (PWA) verwenden. Jedes PWA unterscheidet sich und kann unterschiedliche Caching-Strategien verwenden. Ihr Code sieht möglicherweise anders aus, und Sie können unterschiedliche Cache-Strategien für unterschiedliche Routen innerhalb derselben Anwendung verwenden.

Verwenden von IndexedDB in Ihrer PWA zum Speichern strukturierter Daten

IndexedDB ist eine API zum Speichern strukturierter Daten. Ähnlich wie die Cache API ist sie auch asynchron. Dies bedeutet, dass Sie es im Hauptthread oder mit Webmitarbeitern wie Service Workern verwenden können. Verwenden Sie die IndexedDB API zum Speichern einer erheblichen Menge strukturierter Daten auf dem Client oder binärer Daten, z. B. verschlüsselte Medienobjekte. Siehe MDN-Einführung zur Verwendung von IndexedDB.

Grundlegendes zu Speicheroptionen für PWAs

Manchmal müssen Sie möglicherweise kleine Datenmengen speichern, um Ihren Benutzern eine bessere Offline-Erfahrung zu bieten. Wenn dies der Fall ist, stellen Sie möglicherweise fest, dass die Einfachheit des Schlüssel-Wert-Paarsystems von Web Storage Ihren Anforderungen entspricht.

Wichtig

Web Storage ist ein synchroner Prozess und steht nicht zur Verwendung in Arbeitsthreads wie Service Workern zur Verfügung. Die starke Nutzung von Web-Storage kann zu Leistungsproblemen für Ihre Anwendung führen.

Es gibt zwei Arten von Web-Storage: localStorage und sessionStorage . Jeder Typ von Web-Storage wird als separater Datenspeicher verwaltet, der von der Domäne isoliert ist, von der er erstellt wurde.

  • sessionStorage wird nur für die Dauer der Browsersitzung beibehalten. Beispielsweise, während der Browser geöffnet ist, einschließlich Aktualisierung und Wiederherstellung.
  • localStorage wird beibehalten, bis die Daten vom Code, vom Benutzer oder vom Browser entfernt werden. Wenn beispielsweise begrenzter Speicher verfügbar ist.

Der folgende Code zeigt die Verwendung localStorage , die der Verwendung sessionStorage ähnelt:

var data = {
    title: document.querySelector("[property='og:title']").getAttribute("content"),
    description: document.querySelector( "meta[name='description']" ).getAttribute("content")
};
localStorage.setItem( window.location, JSON.stringify(data) );

Im obigen Code werden Metadaten zur aktuellen Seite abgerufen und in einem JavaScript-Objekt gespeichert. Anschließend wird dieser Wert als JSON in der Verwendung der Methode gespeichert localStorage setItem() und ein Schlüssel zugewiesen, der der aktuellen window.location URL entspricht. Sie können die Informationen localStorage mithilfe der getItem() Methode abrufen.

Der folgende Code zeigt, wie Sie die Zwischenspeicherung localstorage verwenden, um zwischengespeicherte Seiten aufzuführen und Metadaten zu extrahieren, um eine Aufgabe auszuführen, z. B. das Erstellen einer Liste von Links.

caches.open( "pages" )
      .then( cache => {
    cache.keys()
         .then( keys => {
        if ( keys.length )
        {
            keys.forEach( insertOfflineLink );
        }
    })
});

function insertOfflineLink( request ) {
    var data = JSON.parse( localStorage.getItem( request.url ) );
    // If data exists and this page isn't an offline page (assumes that offline 
    // pages have the word "offline" in the URL).
    if ( data && request.url.indexOf('offline') < 0  )
    {
        // Build a link and insert it into the page.
    }
}

Die insertOfflineLink() Methode übergibt die URL der Anforderung an die localStorage.getItem() Methode, um gespeicherte Metadaten abzurufen. Die abgerufenen Daten werden überprüft, um festzustellen, ob sie vorhanden sind, und wenn dies der Fall ist, kann eine Aktion für die Daten ausgeführt werden, z. B. erstellen und einfügen des Markups, um sie anzuzeigen.

Testen auf Netzwerkverbindungen in Ihrer PWA

Zusätzlich zum Speichern von Informationen für die Offlineverwendung ist es hilfreich zu wissen, wann eine Netzwerkverbindung verfügbar ist, um Daten zu synchronisieren oder Benutzer darüber zu informieren, dass sich der Netzwerkstatus geändert hat.

Verwenden Sie die folgenden Optionen, um die Netzwerkkonnektivität zu testen:

Die navigator.onLine Eigenschaft ist ein boolescher Wert, der Sie über den aktuellen Status des Netzwerks informiert. Wenn der Wert true ist, ist der Benutzer online, andernfalls ist der Benutzer offline.

Online- und Offlineereignisse

Sie können Maßnahmen ergreifen, wenn sich die Netzwerkkonnektivität ändert. Sie können als Reaktion auf Netzwerkereignisse zuhören und Maßnahmen ergreifen. Die Ereignisse sind für die , window document und Elemente document.body verfügbar, wie unten dargestellt:

window.addEventListener("online",  function(){
    console.log("You are online!");
});
window.addEventListener("offline", function(){
    console.log("Oh no, you lost your network connection.");
});

Weitere Informationen