Hier finden Sie Best Practices für die Synchronisierung des Anwendungsstatus zwischen IndexedDB und gängigen Bibliotheken für die Statusverwaltung.
Wenn ein Nutzer eine Website oder Anwendung zum ersten Mal lädt, ist oft ein erheblicher Aufwand erforderlich, um den anfänglichen Anwendungsstatus zu erstellen, der zum Rendern der Benutzeroberfläche verwendet wird. Manchmal muss die App beispielsweise den Nutzer clientseitig authentifizieren und dann mehrere API-Anfragen stellen, bevor sie alle Daten hat, die sie auf der Seite anzeigen muss.
Wenn Sie den Anwendungsstatus in IndexedDB speichern, können Sie die Ladezeit für wiederholte Besuche verkürzen. Die App kann dann im Hintergrund mit allen API-Diensten synchronisiert werden und die Benutzeroberfläche mit neuen Daten aktualisieren, wobei eine stale-while-revalidate-Strategie verwendet wird.
Bei der Verwendung von IndexedDB gibt es jedoch viele wichtige Dinge zu beachten, die für Entwickler, die mit den APIs noch nicht vertraut sind, möglicherweise nicht sofort offensichtlich sind. In diesem Dokument werden häufig gestellte Fragen beantwortet und einige der wichtigsten Punkte erläutert, die Sie beim Speichern des Anwendungsstatus in IndexedDB beachten sollten.
App-Verhalten vorhersehbar halten
Viele der komplexen Probleme im Zusammenhang mit IndexedDB ergeben sich daraus, dass es so viele Faktoren gibt, auf die Sie als Entwickler keinen Einfluss haben. In diesem Abschnitt werden viele der Probleme behandelt, die Sie bei der Arbeit mit IndexedDB beachten müssen.
Schreibvorgänge in den Speicher können fehlschlagen
Fehler beim Schreiben in IndexedDB können aus verschiedenen Gründen auftreten. In einigen Fällen liegen diese Gründe außerhalb Ihrer Kontrolle als Entwickler. In einigen Browsern ist es beispielsweise nicht möglich, im privaten Browsermodus in IndexedDB zu schreiben. Es ist auch möglich, dass ein Nutzer ein Gerät verwendet, auf dem der Speicherplatz fast aufgebraucht ist. In diesem Fall verhindert der Browser, dass überhaupt etwas gespeichert wird.
Daher ist es wichtig, dass Sie in Ihrem IndexedDB-Code immer eine ordnungsgemäße Fehlerbehandlung implementieren. Das bedeutet auch, dass es im Allgemeinen eine gute Idee ist, den Anwendungsstatus im Arbeitsspeicher zu behalten (zusätzlich zum Speichern), damit die Benutzeroberfläche nicht beschädigt wird, wenn sie im privaten Browsermodus ausgeführt wird oder wenn kein Speicherplatz verfügbar ist (auch wenn einige der anderen App-Funktionen, die Speicherplatz erfordern, nicht funktionieren).
Gespeicherte Daten wurden möglicherweise vom Nutzer geändert oder gelöscht
Im Gegensatz zu serverseitigen Datenbanken, bei denen Sie unbefugten Zugriff einschränken können, sind clientseitige Datenbanken für Browsererweiterungen und Entwicklertools zugänglich und können vom Nutzer gelöscht werden.
Es ist zwar ungewöhnlich, dass Nutzer ihre lokal gespeicherten Daten ändern, aber es kommt häufig vor, dass sie sie löschen. Es ist wichtig, dass Ihre Anwendung beide Fälle ohne Fehler verarbeiten kann.
Die gespeicherten Daten sind möglicherweise veraltet
Ähnlich wie im vorherigen Abschnitt ist es auch möglich, dass die Daten im Speicher von einer früheren Version Ihres Codes geschrieben wurden, möglicherweise einer Version mit Fehlern, selbst wenn der Nutzer die Daten nicht selbst geändert hat.
IndexedDB bietet integrierte Unterstützung für Schemaversionen und Upgrades mit der Methode IDBOpenDBRequest.onupgradeneeded(). Sie müssen Ihren Upgrade-Code jedoch so schreiben, dass er den Nutzer verarbeiten kann, der von einer früheren Version (einschließlich einer Version mit einem Fehler) kommt.
Unit-Tests können hier sehr hilfreich sein, da es oft nicht möglich ist, alle möglichen Upgradepfade und ‑fälle manuell zu testen.
App-Leistung aufrechterhalten
Eine der wichtigsten Funktionen von IndexedDB ist die asynchrone API. Das bedeutet jedoch nicht, dass Sie sich bei der Verwendung keine Gedanken über die Leistung machen müssen. Es gibt eine Reihe von Fällen, in denen eine unsachgemäße Verwendung den Hauptthread blockieren kann, was dazu führen kann, dass die Seite nicht mehr reagiert.
Generell sollten Lese- und Schreibvorgänge in IndexedDB nicht größer sein, als für die Daten, auf die zugegriffen wird, erforderlich ist.
Mit IndexedDB können große, verschachtelte Objekte als einzelner Datensatz gespeichert werden. Das ist aus Entwicklersicht zwar sehr praktisch, sollte aber vermieden werden. Das liegt daran, dass IndexedDB beim Speichern eines Objekts zuerst einen strukturierten Klon dieses Objekts erstellen muss. Der strukturierte Klonvorgang erfolgt im Hauptthread. Je größer das Objekt, desto länger ist die Blockierungszeit.
Das stellt eine Herausforderung dar, wenn Sie planen, wie der Anwendungszustand in IndexedDB persistent gespeichert werden soll, da die meisten gängigen Bibliotheken für die Zustandsverwaltung (wie Redux) den gesamten Zustandsbaum als einzelnes JavaScript-Objekt verwalten.
Diese Art der Statusverwaltung hat viele Vorteile. Es mag auch verlockend und praktisch sein, den gesamten Statusbaum als einzelnen Eintrag in IndexedDB zu speichern. Wenn Sie dies jedoch nach jeder Änderung tun (selbst wenn sie gedrosselt/entprellt wird), führt dies zu einer unnötigen Blockierung des Hauptthreads, erhöht die Wahrscheinlichkeit von Schreibfehlern und führt in einigen Fällen sogar dazu, dass der Browsertab abstürzt oder nicht mehr reagiert.
Anstatt den gesamten Statusbaum in einem einzigen Datensatz zu speichern, sollten Sie ihn in einzelne Datensätze aufteilen und nur die Datensätze aktualisieren, die sich tatsächlich ändern.
Wie bei den meisten Best Practices ist dies keine Alles-oder-Nichts-Regel. Wenn es nicht möglich ist, ein Zustandsobjekt aufzuteilen und nur den minimalen Änderungssatz zu schreiben, ist es immer noch besser, die Daten in Unterbäume aufzuteilen und nur diese zu schreiben, als immer den gesamten Zustandsbaum zu schreiben. Kleine Verbesserungen sind besser als gar keine Verbesserungen.
Schließlich solltet ihr immer die Auswirkungen des von euch geschriebenen Codes auf die Leistung messen. Es stimmt zwar, dass kleine Schreibvorgänge in IndexedDB besser funktionieren als große, aber das ist nur dann relevant, wenn die Schreibvorgänge in IndexedDB, die Ihre Anwendung ausführt, tatsächlich zu Long Tasks führen, die den Hauptthread blockieren und die Nutzererfahrung beeinträchtigen. Es ist wichtig, Messungen durchzuführen, damit Sie wissen, was Sie optimieren.
Zusammenfassung
Entwickler können clientseitige Speichermechanismen wie IndexedDB verwenden, um die Nutzerfreundlichkeit ihrer Anwendung zu verbessern. Dabei wird nicht nur der Status über Sitzungen hinweg beibehalten, sondern auch die Zeit verkürzt, die zum Laden des Anfangsstatus bei wiederholten Besuchen erforderlich ist.
Die richtige Verwendung von IndexedDB kann die Nutzerfreundlichkeit erheblich verbessern. Eine falsche Verwendung oder das Versäumnis, Fehlerfälle zu beheben, kann jedoch zu fehlerhaften Apps und unzufriedenen Nutzern führen.
Da der Clientspeicher viele Faktoren umfasst, die außerhalb Ihrer Kontrolle liegen, ist es wichtig, dass Ihr Code gut getestet ist und Fehler ordnungsgemäß verarbeitet, auch solche, die auf den ersten Blick unwahrscheinlich erscheinen.