Um die Technologie, die PWAs zuverlässig, installierbar und funktionsfähig macht, optimal zu nutzen, sollten Sie zuerst Ihre Anwendung und ihre Einschränkungen verstehen und eine geeignete Architektur für beide auswählen.
SPA im Vergleich zu MPA
Heute gibt es in der Webentwicklung zwei primäre Architekturmuster: Single-Page-Anwendungen oder SPAs und Multi-Page-Anwendungen (MPAs).
Bei Single-Page-Apps wird das meiste oder gesamte HTML-Rendering einer Seite über clientseitiges JavaScript gesteuert, basierend auf Daten, die von der App abgerufen oder bereitgestellt werden. Die App überschreibt die integrierte Navigation des Browsers und ersetzt sie durch ihre Routing- und Ansichtsverwaltungsfunktionen.
Bei mehrseitigen Apps wird in der Regel vorgefertigtes HTML direkt an den Browser gesendet. Dieses wird oft nach dem Laden des HTML-Codes durch clientseitiges JavaScript ergänzt. Für die Anzeige nachfolgender Ansichten werden die integrierten Navigationsmechanismen des Browsers verwendet.
Beide Architekturen können zum Erstellen von PWAs verwendet werden.
Jedes hat Vor- und Nachteile. Die richtige Auswahl für Ihren Anwendungsfall und Kontext ist entscheidend, um Ihren Nutzern eine schnelle und zuverlässige Nutzung zu ermöglichen.
Einseitige Apps
- Vorwiegend atomare In-Page-Aktualisierungen.
- Clientseitige Abhängigkeiten, die beim Start geladen werden.
- Nachfolgende Ladevorgänge erfolgen aufgrund der Cache-Nutzung schnell.
- Hohe Kosten für den anfänglichen Datenupload.
- Die Leistung hängt von der Gerätehardware und der Netzwerkverbindung ab.
- Die App-Komplexität ist höher.
Einseitige Web-Apps eignen sich gut für folgende Anwendungsfälle:
- Die Nutzerinteraktion konzentriert sich hauptsächlich auf atomare Aktualisierungen von miteinander verbundenen Daten, die auf derselben Seite angezeigt werden, z. B. in einem Echtzeit-Datendashboard oder einer Videobearbeitungs-App.
- Ihre Anwendung hat nur clientseitige Abhängigkeiten bei der Initialisierung, z. B. einen Authentifizierungsanbieter von Drittanbietern mit unerschwinglich hohen Startkosten.
- Die Daten, die zum Laden einer Ansicht erforderlich sind, hängen von einem bestimmten clientseitigen Kontext ab, z. B. der Anzeige von Steuerelementen für eine verbundene Hardware.
- Die App ist klein und einfach genug, dass ihre Größe und Komplexität keine Auswirkungen auf die oben aufgeführten Nachteile hat.
SPAs sind in folgenden Fällen möglicherweise keine gute Wahl für die Architektur:
- Die Leistung beim ersten Laden ist entscheidend. SPAs müssen in der Regel mehr JavaScript-Code laden, um zu bestimmen, was geladen werden soll und wie es angezeigt wird. Das Parsen und Ausführen dieses JavaScripts in Kombination mit dem Abrufen von Inhalten ist langsamer als das Senden von gerendertem HTML.
- Ihre App wird hauptsächlich auf Geräten mit geringer bis durchschnittlicher Leistung ausgeführt. Da SPAs für das Rendering auf JavaScript angewiesen sind, hängt die Nutzererfahrung viel stärker von der Leistung des jeweiligen Geräts ab als bei einer MPA.
Da SPAs die integrierte Navigation des Browsers durch ihr Routing ersetzen müssen, ist ein Mindestmaß an Komplexität erforderlich, um die aktuelle Ansicht effizient zu aktualisieren, Navigationsänderungen zu verwalten und frühere Ansichten zu bereinigen, die sonst vom Browser verarbeitet werden würden. Dadurch werden sie insgesamt schwieriger zu verwalten und auf dem Gerät des Nutzers höher.
Mehrseitige Apps
- Vorwiegend Aktualisierungen auf einer ganzen Seite.
- Die anfängliche Rendergeschwindigkeit ist entscheidend.
- Clientseitiges Scripting kann eine Verbesserung sein.
- Sekundäre Ansichten erfordern einen weiteren Serveraufruf.
- Der Kontext wird nicht in andere Ansichten übertragen.
- Erfordert einen Server oder Pre-Rendering.
Mehrseitige Apps sind eine gute architektonische Wahl, wenn:
- Die Nutzerinteraktion konzentriert sich hauptsächlich auf Ansichten eines einzelnen Datenelements mit optionalen kontextbezogenen Daten, z. B. in einer Nachrichten- oder E-Commerce-App.
- Die anfängliche Rendering-Geschwindigkeit ist entscheidend, da das Senden von bereits gerendertem HTML-Code an den Browser schneller ist als das Zusammenstellen aus einer Datenanforderung nach dem Laden, Parsen und Ausführen einer JavaScript-basierten Alternative.
- Clientseitige Interaktivität oder Kontext können nach dem ersten Laden als Verbesserung hinzugefügt werden, z. B. ein Profil auf eine gerenderte Seite legen oder sekundäre clientseitige kontextabhängige Komponenten hinzufügen.
MPAs sind möglicherweise keine gute Architekturwahl, wenn:
- Das erneute Herunterladen, Parsen und Ausführen von JavaScript oder CSS ist unerschwinglich teuer. Dieser Nachteil wird bei PWAs mit Service Workern minimiert.
- Clientseitiger Kontext, z. B. der Standort des Nutzers, wird nicht nahtlos zwischen den Ansichten übertragen. Das erneute Abrufen dieses Kontexts kann teuer sein. Sie muss entweder zwischen den Aufrufen erfasst und abgerufen oder noch einmal angefordert werden.
Weil einzelne Ansichten vor dem Zugriff dynamisch von einem Server gerendert oder vorab gerendert werden müssen, was das Hosting einschränken oder die Datenkomplexität erhöhen kann.
Welchen sollten Sie wählen?
Trotz dieser Vor- und Nachteile sind beide Architekturen für die Erstellung Ihrer PWA geeignet. Sie können sie je nach Bedarf auch für verschiedene Teile Ihrer App kombinieren, z. B. Store-Einträge nach einer MPA-Architektur und den Bezahlvorgang nach einer SPA-Architektur.
Unabhängig von der Wahl besteht der nächste Schritt darin, zu verstehen, wie Sie Service Worker am besten verwenden, um die beste Nutzererfahrung zu bieten.
Die Vorteile von Service Workern
Der Dienst-Worker bietet weit mehr als nur grundlegendes Routing und die Bereitstellung von gecachten und Netzwerkantworten. Wir können komplexe Algorithmen erstellen, die die Nutzerfreundlichkeit und Leistung verbessern.
Service Worker umfasst (SWI)
Ein neues Muster für die Nutzung von Service Workern als wesentlicher Bestandteil der Architektur einer Website sind Service Worker (SWI). SWI teilt einzelne Assets, in der Regel eine HTML-Seite, je nach Caching-Anforderungen in Teile auf und setzt sie dann im Service Worker wieder zusammen, um Konsistenz, Leistung und Zuverlässigkeit zu verbessern und gleichzeitig die Cache-Größe zu reduzieren.
Dieses Bild ist eine Beispielwebseite. Die Seite ist in fünf verschiedene Abschnitte unterteilt:
- Gesamtlayout
- Allgemeine Kopfzeile (dunkle obere Leiste)
- Inhaltsbereich (Linien und Bild in der Mitte links)
- Seitenleiste (hohe, mitteldunkle Leiste in der Mitte rechts)
- Fußzeile (dunkle untere Leiste)
Gesamtlayout
Das Gesamtlayout ändert sich wahrscheinlich nicht oft und hat keine Abhängigkeiten. Sie eignet sich gut für das Vorab-Caching.
Kopf- und Fußzeile
Die globale Kopf- und Fußzeile enthalten Elemente wie das obere Menü und die Fußzeile der Website und stellen eine besondere Herausforderung dar: Wenn die Seite als Ganzes im Cache gespeichert werden soll, können sich diese zwischen dem Laden der Seite ändern, je nachdem, wann die jeweilige Seite im Cache gespeichert wurde.
Wenn Sie sie trennen und unabhängig vom Inhalt im Cache speichern, können Sie dafür sorgen, dass Nutzer immer dieselbe Version erhalten, unabhängig davon, wann sie im Cache gespeichert wird. Da sie selten aktualisiert werden, eignen sie sich auch gut für das Pre-Caching. Sie sind jedoch von den CSS- und JavaScript-Dateien der Website abhängig.
CSS und JavaScript
Idealerweise sollten die CSS- und JavaScript-Codes der Website mit einer veralteten Strategie im Cache gespeichert werden, um inkrementelle Aktualisierungen zu ermöglichen, ohne den Service Worker aktualisieren zu müssen, wie es bei vorab im Cache gespeicherten Assets der Fall ist. Dennoch müssen sie immer auf die Mindestversion beschränkt sein, wenn der Service Worker mit einer neuen globalen Kopf- oder Fußzeile aktualisiert wird. Daher sollte der Cache auch mit der neuesten Version der Assets aktualisiert werden, wenn der Service Worker installiert wird.
Inhaltsbereich
Als Nächstes folgt der Inhaltsbereich. Je nach Häufigkeit der Aktualisierungen ist entweder „Netzwerk zuerst“ oder „Veraltet bei erneuter Validierung“ eine gute Strategie. Bilder sollten mit einer Strategie im Cache gespeichert werden, wie zuvor erläutert wurde.
Seitenleiste
Angenommen, die Seitenleiste enthält sekundäre Inhalte wie Tags und ähnliche Elemente, sind diese nicht wichtig genug, um sie aus dem Netzwerk abzurufen. Hier eignet sich die Strategie „Stale while revalidate“.
Nachdem Sie das alles durchgegangen sind, denken Sie vielleicht, dass Sie diese Art des Cachens pro Abschnitt nur für Single-Page-Apps verwenden können. Wenn Sie jedoch Muster verwenden, die von Edge-Side-Includes oder Server-Side-Includes in Ihrem Service Worker mit einigen erweiterten Service Worker-Funktionen inspiriert sind, können Sie dies für beide Architekturen tun.
Selbst ausprobieren
Sie können die Dienstworker-Includes im nächsten Codelab ausprobieren:
Streamingantworten
Die vorherige Seite könnte mit dem App-Shell-Modell in der SPA-Welt erstellt werden, bei dem die App-Shell im Cache gespeichert, dann bereitgestellt und die Inhalte clientseitig geladen werden. Mit der Einführung und der breiten Verfügbarkeit der Streams API können sowohl die App-Shell als auch die Inhalte im Service Worker kombiniert und an den Browser gestreamt werden. So erhalten Sie die Caching-Flexibilität der App-Shell mit der Geschwindigkeit von MPAs.
Das hat folgende Gründe:
- Streams können asynchron erstellt werden, sodass verschiedene Teile eines Streams aus anderen Quellen stammen können.
- Der Anforderer eines Streams kann mit der Antwort beginnen, sobald der erste Datenblock verfügbar ist, anstatt auf die Fertigstellung des gesamten Elements zu warten.
- Für Streaming optimierte Parser, einschließlich des Browsers, können den Inhalt des Streams schrittweise anzeigen, bevor er vollständig ist. Dadurch wird die wahrgenommene Leistung der Antwort beschleunigt.
Aufgrund dieser drei Eigenschaften von Streams haben Architekturen, die auf Streaming basieren, in der Regel eine höhere wahrgenommene Leistung als solche, die dies nicht tun.
Die Arbeit mit der Streams API kann schwierig sein, da sie komplex und niedrig ist. Glücklicherweise gibt es ein Workbox-Modul, das Ihnen beim Einrichten von Streamingantworten für Ihre Service Worker helfen kann.
Domains, Ursprünge und PWA-Bereich
Webworker, einschließlich Serviceworker, Speicher und sogar das Fenster einer installierten PWA, unterliegen einem der wichtigsten Sicherheitsmechanismen im Web: der Richtlinie zum gleichen Ursprung. Innerhalb desselben Ursprungs werden Berechtigungen gewährt, Daten können freigegeben werden und der Service Worker kann mit verschiedenen Clients kommunizieren. Außerhalb desselben Ursprungs werden Berechtigungen nicht automatisch gewährt. Daten sind dann voneinander getrennt und nicht für andere Ursprünge zugänglich.
Richtlinie zum gleichen Ursprung
Zwei URLs haben denselben Ursprung, wenn Protokoll, Port und Host identisch sind.
Beispiel: https://squoosh.app
und https://squoosh.app/v2
haben denselben Ursprung, http://squoosh.app
, https://squoosh.com
, https://app.squoosh.app
und https://squoosh.app:8080
jedoch unterschiedliche Ursprünge. Weitere Informationen und Beispiele finden Sie in der MDN-Referenz zur Richtlinie zum gleichen Ursprung.
Ein Host kann sich nicht nur durch das Ändern von Subdomains ändern. Jeder Host besteht aus einer Top-Level-Domain (TLD), einer Second-Level-Domain (SLD) und null oder mehr Labels (manchmal auch Subdomains genannt), die durch Punkte voneinander getrennt sind und in einer URL von rechts nach links gelesen werden. Eine Änderung an einem der Elemente führt zu einem anderen Host.
Im Modul zur Fensterverwaltung haben wir bereits gesehen, wie der In-App-Browser aussieht, wenn ein Nutzer von einer installierten PWA zu einem anderen Ursprung navigiert.
Dieser In-App-Browser wird auch angezeigt, wenn die Websites dieselbe TLD und SLD, aber unterschiedliche Labels haben, da sie dann als unterschiedliche Ursprünge betrachtet werden.
Einer der wichtigsten Aspekte des Ursprungs im Zusammenhang mit dem Surfen ist die Funktionsweise von Speicher und Berechtigungen. Eine Quelle teilt viele Funktionen mit allen Inhalten und PWAs darin, darunter:
- Speicherkontingent und ‑daten (IndexedDB, Cookies, Webspeicher, Cachespeicher)
- Service Worker-Registrierungen
- Gewährte oder abgelehnte Berechtigungen (z. B. Web-Push, Standortbestimmung, Sensoren)
- Web-Push-Registrierungen
Wenn Sie von einem Ursprung zu einem anderen wechseln, wird der gesamte vorherige Zugriff widerrufen. Berechtigungen müssen also noch einmal gewährt werden und Ihre PWA kann nicht auf alle im Speicher gespeicherten Daten zugreifen.