Blog

Offline-first Progressive Web Apps (PWAs) mit React & Redux erstellen

Aktualisiert Oktober 21, 2025
6 Minuten

Es gibt immer noch viele Orte auf der Welt, an denen der Internetzugang entweder schlecht oder gar nicht vorhanden ist. Ein Flugzeug oder ein Fabrikkeller sind Paradebeispiele dafür - aber das ist natürlich nur die Spitze des Eisbergs. Wenn Sie eine mobile App anbieten, ist es eine Herausforderung, sie unter solchen Bedingungen zum Laufen zu bringen.

Bei meinem letzten Projekt hatte ich eine solche Herausforderung und beschloss, meine Erfahrungen zu teilen. Jetzt ist es an der Zeit, Ihnen einige Tipps zu geben, wie Sie Webanwendungen erstellen können, die vollständig offline funktionieren.

Wie funktioniert es standardmäßig?

PWAs sind Web-Apps mit einigen zusätzlichen Funktionen. Standardmäßig werden Sie im Offline-Modus mit dem berüchtigten T-Rex begrüßt (zumindest wenn Sie Chrome verwenden), wie auf jeder anderen Webseite auch - aber wir haben alle Tools, um dies zu ändern!

PWA im Offline-Modus ohne Caching
PWA im Offline-Modus ohne Caching

Lesen Sie Resilienz

 

Das Ziel ist es, den Benutzern den Zugriff auf die App-Dateien und Daten zu ermöglichen, die sie zuvor ohne Netzwerkzugang gesehen haben. Dies ist die perfekte Aufgabe für einen Service Worker - das Vorabholen und Zwischenspeichern von Daten für die spätere Verwendung. Es ist keine große Sache, SW anzuweisen, alle Ressourcen zwischenzuspeichern, die Sie für den Betrieb Ihrer PWA für notwendig erachten. Wenn Sie Ihr Projekt mit CRA gebootet haben, sind bereits vordefinierte Regeln und ein Skript zur Erzeugung von Service Workern enthalten.

Aber es gibt ein Problem - sie sind nicht sehr flexibel. Daher habe ich schließlich meine eigene Konfiguration mit Workbox verwendet. Weitere Einzelheiten zur Verwendung des benutzerdefinierten Service Workers in CRA finden Sie hier. Die Standardkonfiguration reicht aus, wenn Sie sich nur um die Zwischenspeicherung statischer Elemente wie JS, CSS-Dateien, Schriftarten oder Bilder kümmern. Ich wollte etwas mehr - Übersetzungen und Daten, die in meinem Fall beide von unserer REST-API kamen.

Da ich den Endpunkt /translations/{locale} nicht im Anwendungsstatus behalte (der von Redux verwaltet wird), sondern ihn einfach an das i18next-Plugin übergebe, hielt ich es für eine gute Idee, dem Service Worker mitzuteilen, dass er seine Antwort ebenfalls zwischenspeichern soll.

Unten sehen Sie mein Setup mit Caching für Übersetzungen:

Aber was ist mit den Daten, die von der API kommen? Ich habe erwähnt, dass der Zustand der Anwendung von Redux verwaltet wird. Ich werde nicht zu sehr in die Tiefe gehen, was Redux ist - wenn Sie es nicht sehr gut kennen, haben Sie wahrscheinlich zumindest davon gehört. Aber eine wichtige Sache, die Sie sich über Redux merken müssen, ist, dass der Anwendungsstatus in einem einzigen Objekt namens Redux store gespeichert wird. Und da es sich um ein einziges Objekt handelt, ist es auch einfach, dieses Objekt irgendwo im Browser zu speichern.

Es gibt ein Paket, das genau das tut: redux-persist. Standardmäßig speichert es den Status in localStorage, so dass Sie alles, was Sie zuvor in Ihrem Redux-Speicher hatten, auch im Offline-Modus anzeigen können. Sie können auch einen anderen Speichermechanismus verwenden, wie z.B. IndexedDB. Dies kann die bessere Wahl sein, wenn Sie sich Sorgen um die Speichergröße machen.

Nebenbei bemerkt: Redux-persist ist ein sehr beliebtes Paket in der React Native-Entwicklung, um das Verhalten einer Native App bei der Persistierung des Zustands zwischen Sitzungen in AsyncStorage zu imitieren.

Nach all diesen Schritten kann der Benutzer nun auf Ihre App im Offline-Modus zugreifen. Herzlichen Glückwunsch!

Aber das war nur der erste Schritt.

PWA im Offline-Modus mit SW-Caching und redux-persist
PWA im Offline-Modus mit SW-Caching und redux-persist

Resilienz schreiben

 

Wie Sie auf den Bildschirmen sehen können, hat unsere App ein paar "Plus"-Symbole. Wir könnten hier aufhören und sagen: "Tut uns leid, das Hinzufügen oder Bearbeiten von Daten wird im Offline-Modus nicht unterstützt", was für einige Unternehmen völlig in Ordnung ist. Aber was ist, wenn diese Funktion für ein bestimmtes Unternehmen sehr gefragt (oder sogar entscheidend) ist? Konzentrieren wir uns zunächst darauf, wie wir normalerweise mit der API kommunizieren und auf ihre Antwort reagieren:

Hinzufügen eines neuen Kontakts - die Benutzeroberfläche wird nach der erfolgreichen API-Antwort aktualisiert
Hinzufügen eines neuen Kontakts - die Benutzeroberfläche wird nach der erfolgreichen API-Antwort aktualisiert

Das ist in Ordnung für Apps, die eine Internetverbindung benötigen, um verfügbar zu sein. Da wir uns im Offline-Modus natürlich nicht auf die API verlassen können, sollten wir vielleicht die Benutzeroberfläche sofort aktualisieren und die API-Aktualisierung im Hintergrund auslösen?

Optimistische UI

 

Es gibt ein UX-Muster für ein solches Verhalten, das Optimistic UI genannt wird. Es scheint für unseren Fall eine gute Wahl zu sein. Bei diesem Ansatz aktualisieren wir die Benutzeroberfläche unabhängig von der API-Antwort und gehen davon aus, dass die Mehrheit der Anfragen erfolgreich sein wird. Hier sehen Sie, wie das Hinzufügen eines neuen Kontakts mit diesem Muster aussehen wird:

Neuen Kontakt hinzufügen - Optimistischer UI-Ansatz
Neuen Kontakt hinzufügen - Optimistischer UI-Ansatz

Wie wird sich dies im Offline-Modus ändern? In Bezug auf die Benutzeroberfläche nicht viel - wir werden nur den linearen Fortschritt nicht anzeigen, da wir die API nicht offline aufrufen können. Dennoch müssen wir dafür sorgen, dass dieser Aufruf ausgelöst wird, wenn wir wieder online sind. Wir könnten die Logik selbst implementieren, aber anstatt das Rad neu zu erfinden, sehen wir uns an, was das redux-offline Paket zu bieten hat.

redux-offlinePersistenter Redux-Speicher für Reasonaboutable ™️ Offline-First-Anwendungen, mit erstklassiger Unterstützung für optimistische UI...www.npmjs.com

Sieht aus, als hätte es alles, was wir brauchen... und noch mehr! Um nur ein paar der wichtigsten Funktionen zu nennen:

  • Eingebautes redux-persist zum Speichern des Offline-Status mit der Möglichkeit zum Opt-Out und zur Verwendung benutzerdefinierter Einstellungen
  • Offline/Online-Erkennungsmechanismus
  • Warteschlange für Anfragen verwalten
  • Wiederholungsmechanismus bei fehlerhaften Netzwerken

Das Einzige, worauf wir nach der Einrichtung der Bibliothek achten müssen, ist, dass wir immer ein bestimmtes Format für alle redux-Aktionen verwenden, die Daten an das Backend senden müssen. Hier ist ein Beispiel dafür, wie das Hinzufügen eines neuen Kontakts mit redux-offline aussieht:In diesem Fall wird die optimistische Aktualisierung direkt nach dem Versand der Aktion Kontaktperson/Erstellen durchgeführt. Die anderen 2 Aktionen werden nur ausgelöst, wenn der Benutzer online ist.

Redux-Offline-Aktionen Dispatching-Logik
Redux-Offline-Aktionen Dispatching-Logik

Das einzige Teil des Puzzles, das ich noch nicht erklärt habe, ist, warum wir IDs für neue Entitäten auf der Client-Seite erzeugen. Das liegt an den Beziehungen. Stellen Sie sich vor, wir möchten unseren neu erstellten Kontakt im Offline-Modus in einer anderen Anfrage verwenden. Dies könnte zum Beispiel ein Kontakt sein, der einer Besuchsnotiz zugeordnet wird. Vergessen Sie nicht, dass wir immer noch OFFLINE sind. Um die Daten nicht zu duplizieren, sollte die Nutzlast in dieser neuen Anfrage die ID des Kontakts enthalten, den wir zuvor erstellt haben.

PUT /Besuch-Notiz/1
{
visitDate: '2020-10-23',
Notiz: 'Mein Besuch',
contactPersonId: 'uuid-generated-on-client-side'
}

Da die vorherige POST-Anfrage noch nicht an die API gegangen ist, können wir uns natürlich nicht auf die serverseitig generierten IDs verlassen. Sobald die Verbindung wieder steht, werden alle Anfragen aus der Warteschlange nacheinander in der Reihenfolge ausgelöst, in der sie in die Offline-Warteschlange gestellt wurden. Das heißt, wir haben jetzt die Möglichkeit, die Daten im Offline-Modus zu ändern.

Fazit

Es ist keine triviale Aufgabe, Offline-Unterstützung zu Ihrer App hinzuzufügen. Glücklicherweise ist dies dank Service Workern und Bibliotheken wie redux-persist und redux-offline kein großer Entwicklungsaufwand - Sie müssen nur die Konzepte verstehen, um sie ohne Verwirrung zu verwenden.

Wir hoffen, dass dieser Artikel etwas von der Magie hinter der Offline-First-Architektur enthüllt hat und Ihnen dabei hilft, diese Funktionalität in Ihre Projekte einzubauen!

Contact

Let’s discuss how we can support your journey.