Architektur

Wenn Sie Ihre App so gestalten, dass Sie die Technologie optimal nutzen können, die PWAs zuverlässig, installierbar und fähig macht, müssen Sie Ihre Anwendung und ihre Einschränkungen verstehen und eine geeignete Architektur für beides auswählen.

SPA und MPA im Vergleich

Heutzutage gibt es in der Webentwicklung zwei primäre Architekturmuster: Single-Page-Apps (SPAs) und mehrseitige Apps (MPAs).

Einseitige Apps werden definiert, indem das clientseitige JavaScript die meisten oder das gesamte HTML-Rendering einer Seite auf der Grundlage von Daten gesteuert wird, die von der App abgerufen oder ihr 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 vorab gerenderter HTML-Code direkt an den Browser gesendet. Dieser wird häufig mit clientseitigem JavaScript optimiert, nachdem der Browser den HTML-Code geladen hat, und stützen sich auf die integrierten Navigationsmechanismen des Browsers, um nachfolgende Aufrufe anzuzeigen.

Beide Architekturen können zum Erstellen von PWAs verwendet werden.

Beides hat Vor- und Nachteile. Die Auswahl der richtigen Option für Ihren Anwendungsfall und Kontext ist entscheidend, um Ihren Nutzern eine schnelle und zuverlässige Erfahrung zu bieten.

Einseitige Apps

Vorteile
  • Meistens sehr atomare In-Page-Updates.
  • Clientseitige Abhängigkeiten, die beim Start geladen werden.
  • Nachfolgende Ladevorgänge sind aufgrund der Cache-Nutzung schnell.
Nachteile
  • Hohe Kosten beim ersten Laden.
  • Die Leistung hängt von der Gerätehardware und der Netzwerkverbindung ab.
  • Es ist eine zusätzliche App-Komplexität erforderlich.

Einseitige Apps sind in folgenden Fällen eine gute Architektur:

  • Die Nutzerinteraktion konzentriert sich hauptsächlich auf atomare Updates von miteinander verbundenen Daten, die auf derselben Seite angezeigt werden, z. B. ein Echtzeit-Daten-Dashboard oder eine Videobearbeitungs-App.
  • Ihre Anwendung weist rein clientseitige Initialisierungsabhängigkeiten auf, z. B. von einem Drittanbieter-Authentifizierungsanbieter mit übermäßig hohen Startkosten.
  • Die zum Laden einer Ansicht erforderlichen Daten basieren auf einem bestimmten, nur clientseitigen Kontext. So werden beispielsweise Steuerelemente für eine verbundene Hardware angezeigt.
  • Die App ist klein und einfach genug, dass ihre Größe und Komplexität keine Auswirkungen auf die oben genannten Nachteile haben.

SPAs sind in folgenden Fällen möglicherweise keine gute Architektur:

  • Die anfängliche Ladeleistung ist entscheidend. SPAs müssen in der Regel mehr JavaScript laden, um zu bestimmen, was geladen werden soll und wie es angezeigt werden soll. Das Parsen und Ausführen dieses JavaScripts dauert in Kombination mit dem Abrufen von Inhalten länger als das Senden von gerendertem HTML-Code.
  • Ihre App läuft größtenteils auf Geräten mit geringer bis durchschnittlicher Leistung. Da SPAs beim Rendern auf JavaScript angewiesen sind, hängt die Nutzererfahrung viel stärker von der Leistung ihres jeweiligen Geräts ab als bei einem MPA.

Da SPAs die integrierte Navigation des Browsers durch ihr Routing ersetzen müssen, erfordern SPAs ein Minimum an Komplexität in Bezug auf das effiziente Aktualisieren der aktuellen Ansicht, das Verwalten von Navigationsänderungen und das Bereinigen früherer Ansichten, die sonst vom Browser gehandhabt werden würden. Dadurch wird die Wartung insgesamt erschwerter und die Geräte der Nutzer werden stärker belastet.

Mehrseitige Apps

Vorteile
  • Meistens ganzseitige Updates.
  • Die anfängliche Renderinggeschwindigkeit ist entscheidend.
  • Clientseitiges Scripting kann eine Verbesserung sein.
Nachteile
  • Sekundäre Ansichten erfordern einen weiteren Serveraufruf.
  • Der Kontext kann nicht zwischen den Ansichten übertragen werden.
  • Erfordert einen Server oder Pre-Rendering.

Mehrseitige Apps sind in folgenden Fällen eine gute Architektur:

  • Die Nutzerinteraktion konzentriert sich hauptsächlich auf die Ansicht einzelner Daten mit optionalen kontextbasierten Daten, z. B. einer Nachrichten- oder E-Commerce-App.
  • Die anfängliche Renderinggeschwindigkeit ist entscheidend, da das Senden von bereits gerendertem HTML-Code an den Browser schneller ist als das Zusammenstellen aus einer Datenanfrage nach dem Laden, Parsen und Ausführen einer JavaScript-basierten Alternative.
  • Nach dem ersten Laden können clientseitige Interaktivität oder Kontext als Erweiterung eingebunden werden. Beispielsweise kann ein Profil auf eine gerenderte Seite gelegt oder sekundäre clientseitige kontextabhängige Komponenten hinzugefügt werden.

MPAs sind in folgenden Fällen möglicherweise keine gute Architektur:

  • Das erneute Herunterladen, erneute Parsen und erneute Ausführen von JavaScript oder CSS ist unerschwinglich. Dieser Nachteil wird bei PWAs mit Service Workern minimiert.
  • Clientseitiger Kontext, wie der Nutzerstandort, wird nicht nahtlos zwischen Ansichten übertragen, und das erneute Abrufen dieses Kontextes kann teuer sein. Sie müssen entweder erfasst und abgerufen oder zwischen Ansichten noch einmal angefordert werden.

Weil einzelne Ansichten dynamisch von einem Server gerendert oder vorab gerendert werden müssen, bevor sie darauf zugreifen können. Dadurch wird das Hosting eingeschränkt oder die Datenkomplexität erhöht.

Welche möchtest du auswählen?

Trotz dieser Vor- und Nachteile sind beide Architekturen für das Erstellen Ihrer PWA geeignet. Sie können sie sogar für verschiedene Teile Ihrer App mischen, je nach deren Anforderungen. So können Sie beispielsweise festlegen, dass Store-Einträge einer MPA-Architektur folgen und der Bezahlvorgang einer SPA-Architektur folgt.

Unabhängig von der Entscheidung müssen Sie als Nächstes wissen, wie Sie Service Worker am besten einsetzen, um das bestmögliche Erlebnis zu bieten.

Die Leistungsfähigkeit von Service Workern

Der Service Worker verfügt über viel Leistung über das grundlegende Routing und die Übermittlung von im Cache gespeicherten und Netzwerkantworten hinaus. Wir können komplexe Algorithmen erstellen, um die Nutzererfahrung und Leistung zu verbessern.

Service Worker umfasst (SWI)

Ein aufkommendes Muster für die Nutzung von Service Workern als wesentlichen Bestandteil der Architektur eines Standorts ist Service Worker eingebunden (SWI). SWI teilt einzelne Assets – in der Regel eine HTML-Seite – je nach Caching-Anforderungen in einzelne Teile auf und fügt sie dann im Service Worker zusammen, um Konsistenz, Leistung und Zuverlässigkeit zu verbessern und gleichzeitig die Cache-Größe zu reduzieren. Eine Website mit einer globalen Kopfzeile, einem Inhaltsbereich, einer Seitenleiste und einer Fußzeile.

Dieses Bild ist eine Beispielwebseite. Sie besteht aus fünf verschiedenen Abschnitten, die die Seite in folgende Bereiche unterteilen:

  • Gesamtlayout
  • Globale Kopfzeile (dunkle Leiste oben)
  • Inhaltsbereich (mittlere linke Linien und Bild)
  • Seitenleiste (hoher mitteldunkler Balken rechts in der Mitte).
  • Fußzeile (dunkle Leiste am unteren Rand)

Gesamtlayout

Das Gesamtlayout ändert sich wahrscheinlich nicht häufig und weist keine Abhängigkeiten auf. Sie eignet sich gut für Precaching.

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 wird, können sich diese beim Seitenaufbau ändern, je nachdem, wann die jeweilige Seite im Cache gespeichert wurde.

Indem Sie sie trennen und unabhängig vom Inhalt im Cache speichern, stellen Sie sicher, dass Nutzer immer die gleiche Version erhalten, unabhängig davon, wann sie im Cache gespeichert werden. Da sie selten aktualisiert werden, eignen sie sich auch gut für das Precaching. Sie hängen jedoch vom CSS- und JavaScript-Code der Website ab.

CSS und JavaScript

Idealerweise sollten das CSS und die JavaScript-Datei der Website mit einer veralteten Strategie während der Neuvalidierung im Cache gespeichert werden, um inkrementelle Updates 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 einer Mindestversion gehalten werden, wenn der Service Worker mit einer neuen globalen Kopf- oder Fußzeile aktualisiert. Aus diesem Grund sollte der Cache des Service Workers auch mit der neuesten Version der Assets aktualisiert werden.

Inhaltsbereich

Als Nächstes folgt der Inhaltsbereich. Je nach Häufigkeit der Updates ist hier entweder die Option „Zuerst das Netzwerk“ oder „Veraltet“ bei der erneuten Validierung eine gute Strategie. Bilder sollten mit einer Cache-First-Strategie im Cache gespeichert werden, wie zuvor erörtert wurde.

Wenn der Inhalt der Seitenleiste sekundäre Inhalte wie Tags und verwandte Elemente enthält, ist ein Abruf aus dem Netzwerk nicht entscheidend. Eine veraltete Strategie für die Neuvalidierung kann dafür verwendet werden.

Nachdem Sie all dies durchgegangen sind, denken Sie vielleicht, dass Sie diese Art von Caching pro Abschnitt nur für Apps mit nur einer Seite durchführen können. Sie können dies jedoch für beide Architekturen tun, wenn Sie Muster im Service Worker auf Basis von Edge-Side-Einschließen- oder Server Side-Includes mit einigen erweiterten Service Worker-Funktionen verwenden.

Selbst ausprobieren

Sie können versuchen, den Service Worker im nächsten Codelab zu verwenden:

Streamingantworten

Die vorherige Seite könnte mit dem App-Shell-Modell in der SPA-Welt erstellt werden. Dabei wird die App-Shell im Cache gespeichert, dann bereitgestellt und die Inhalte clientseitig geladen. Durch die Einführung und umfassende Verfügbarkeit der Streams API können sowohl die App-Shell als auch der Inhalt im Service Worker kombiniert und an den Browser gestreamt werden. So haben Sie die Flexibilität der App-Shell beim Caching mit der Geschwindigkeit von MPAs.

Dies geschieht aus folgenden Gründen:

  • Streams können asynchron erstellt werden, sodass verschiedene Teile eines Streams aus anderen Quellen stammen können.
  • Der Anforderer eines Streams kann mit der Bearbeitung der Antwort beginnen, sobald der erste Datenblock verfügbar ist, anstatt zu warten, bis das gesamte Element abgeschlossen ist.
  • Für Streaming optimierte Parser, einschließlich Browser, können den Inhalt des Streams schrittweise anzeigen, bevor er abgeschlossen ist. Dadurch wird die wahrgenommene Leistung der Antwort beschleunigt.

Dank dieser drei Eigenschaften von Streams wird die wahrgenommene Leistung von Architekturen, die auf Streaming basieren, in der Regel schneller wahrgenommen als solche, die dies nicht sind.

Die Arbeit mit der Streams API kann eine Herausforderung sein, da sie komplex und niedrig ist. Glücklicherweise gibt es ein Workbox-Modul, das Sie beim Einrichten von Streamingantworten für Ihre Service Worker unterstützt.

Domains, Ursprünge und PWA-Bereich

Web Worker wie Service Worker, Speicher und sogar das Fenster einer installierten PWA unterliegen einem der wichtigsten Sicherheitsmechanismen im Web: der Same-Origin-Policy. Innerhalb desselben Ursprungs werden Berechtigungen gewährt, Daten können geteilt werden und der Service Worker kann mit verschiedenen Clients kommunizieren. Außerhalb desselben Ursprungs werden Berechtigungen nicht automatisch gewährt und die Daten sind isoliert und nicht von verschiedenen Ursprüngen aus zugänglich.

Richtlinie für denselben Ursprung

Zwei URLs haben den genauen Ursprung, wenn Protokoll, Port und Host identisch sind.

Beispiel: https://squoosh.app und https://squoosh.app/v2 haben denselben Ursprung, aber http://squoosh.app, https://squoosh.com, https://app.squoosh.app und https://squoosh.app:8080 haben unterschiedliche Ursprünge. Weitere Informationen und Beispiele findest du in der MDN-Referenz der Richtlinie für denselben Ursprung.

Das Ändern von Subdomains ist nicht die einzige Möglichkeit, die ein Host ändern kann. 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 gesehen, wie der In-App-Browser aussieht, wenn ein Nutzer über eine installierte PWA zu einem anderen Ursprung navigiert.

Dieser In-App-Browser wird auch dann angezeigt, wenn die Websites dieselbe TLD und denselben SLD, aber mit unterschiedlichen Labels haben, da sie dann als unterschiedliche Ursprünge betrachtet werden.

Einer der wichtigsten Aspekte eines Ursprungs im Web-Browser-Kontext ist der Speicher und die Berechtigungen. Eine Quelle hat viele Funktionen für alle darin enthaltenen Inhalte und PWAs, z. B.:

  • Speicherkontingent und Daten (IndexedDB, Cookies, Webspeicher, Cache-Speicher)
  • Service Worker-Registrierungen
  • Gewährt oder verweigert (z. B. Web-Push, Standortbestimmung, Sensoren)
  • Web-Push-Registrierungen

Wenn Sie von einem Ursprung zu einem anderen wechseln, wird der gesamte bisherige Zugriff widerrufen. Die Berechtigungen müssen also noch einmal gewährt werden und Ihre PWA kann nicht auf alle im Speicher gespeicherten Daten zugreifen.

Ressourcen