Best Practices für die Speicherung des Anwendungsstatus mit IndexedDB

Best Practices für die Synchronisierung des Anwendungsstatus zwischen IndexedDB und gängigen Bibliotheken zur Statusverwaltung

Wenn ein Nutzer eine Website oder Anwendung zum ersten Mal lädt, ist es oft ziemlich aufwendig, den ursprünglichen Anwendungsstatus zu erstellen, der zum Rendern der Benutzeroberfläche verwendet wird. Manchmal muss die App den Nutzer beispielsweise clientseitig authentifizieren und dann mehrere API-Anfragen stellen, bevor alle Daten verfügbar sind, die auf der Seite angezeigt werden müssen.

Wenn Sie den Anwendungsstatus in IndexedDB speichern, lässt sich die Ladezeit bei wiederholten Besuchen erheblich beschleunigen. Die Anwendung kann sich dann im Hintergrund mit allen API-Diensten synchronisieren und die UI nach und nach mit neuen Daten aktualisieren. Dabei wird die Strategie stale- while-revalidation angewendet.

Bei der Verwendung von IndexedDB sind jedoch viele wichtige Punkte zu beachten, die für Entwickler, die die APIs neu verwenden, möglicherweise nicht sofort offensichtlich sind. In diesem Dokument werden allgemeine Fragen beantwortet und einige der wichtigsten Aspekte erläutert, die beim Speichern des Anwendungsstatus in IndexedDB zu beachten sind.

App vorhersehbar gestalten

Viele der Komplexitäten von IndexedDB resultieren aus der Tatsache, dass es so viele Faktoren gibt, auf die Sie als Entwickler keinen Einfluss haben. In diesem Abschnitt werden viele der Probleme behandelt, die bei der Arbeit mit IndexedDB zu beachten sind.

Schreibvorgänge in den Speicher schlagen möglicherweise fehl

Fehler beim Schreiben in IndexedDB können aus verschiedenen Gründen auftreten. In einigen Fällen haben Sie als Entwickler keinen Einfluss auf diese Ursachen. Beispielsweise erlauben einige Browser das Schreiben in IndexedDB nicht, wenn sich der Nutzer im privaten Browsermodus befindet. Es ist auch möglich, dass ein Nutzer ein Gerät verwendet, auf dem fast kein Speicherplatz mehr verfügbar ist, und der Browser verhindert, dass Sie überhaupt etwas speichern.

Aus diesem Grund ist es von entscheidender Bedeutung, dass Sie im IndexedDB-Code immer eine ordnungsgemäße Fehlerbehandlung implementieren. Das bedeutet auch, dass es im Allgemeinen eine gute Idee ist, den Anwendungsstatus nicht nur zu speichern, sondern auch im Arbeitsspeicher zu halten, damit die Benutzeroberfläche nicht zusammenbricht, wenn die App im Inkognitomodus ausgeführt wird oder 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 Browsererweiterungen und Entwicklertools auf clientseitige Datenbanken zugänglich und können vom Nutzer gelöscht werden.

Es ist zwar ungewöhnlich, dass Nutzer ihre lokal gespeicherten Daten ändern, es ist jedoch üblich, dass Nutzer diese löschen. Es ist wichtig, dass Ihre Anwendung beide Fälle ohne Fehler bewältigen kann.

Gespeicherte Daten sind möglicherweise veraltet

Ähnlich wie im vorherigen Abschnitt ist es auch möglich, dass die Daten, die der Nutzer gespeichert hat, von einer früheren Version Ihres Codes geschrieben wurden, möglicherweise einer Version mit Fehlern.

IndexedDB unterstützt Schemaversionen und Upgrades mithilfe der Methode IDBOpenDBRequest.onupgradeneeded(). Sie müssen Ihren Upgradecode jedoch trotzdem so schreiben, dass er Nutzer aus einer früheren Version (einschließlich einer Version mit einem Fehler) verarbeiten kann.

Hier können Unit-Tests sehr hilfreich sein, da es oft nicht möglich ist, alle möglichen Upgradepfade und ‑fälle manuell zu testen.

App-Leistung aufrechterhalten

Eines der wichtigsten Merkmale von IndexedDB ist die asynchrone API. Sie sollten sich jedoch keine Gedanken über die Leistung bei der Verwendung machen. Es gibt eine Reihe von Fällen, in denen eine unsachgemäße Nutzung den Hauptthread dennoch blockieren kann, was zu einer Unreaktionsfähigkeit führen kann.

In der Regel sollten Lese- und Schreibvorgänge in IndexedDB nicht größer sein als für die zugegriffenen Daten erforderlich.

IndexedDB ermöglicht es zwar, große verschachtelte Objekte in einem einzigen Datensatz zu speichern (und dies ist aus Entwicklerperspektive zugegebenermaßen recht praktisch), sollte jedoch vermieden werden. Das liegt daran, dass IndexedDB beim Speichern eines Objekts zuerst einen strukturierten Klon dieses Objekts erstellen muss und der strukturierte Klonvorgang im Hauptthread erfolgt. Je größer das Objekt, desto länger ist die Blockierzeit.

Das stellt einige Herausforderungen bei der Planung der Speicherung des Anwendungsstatus in IndexedDB dar, da die meisten gängigen Bibliotheken zur Zustandsverwaltung (z. B. Redux) den gesamten Statusbaum als einzelnes JavaScript-Objekt verwalten.

Das Verwalten des Status auf diese Weise hat viele Vorteile. Das Speichern des gesamten Zustandsbaums als einzelner Datensatz in IndexedDB kann verlockend und praktisch sein. Wenn Sie dies jedoch nach jeder Änderung (selbst bei gedrosselter/entprellter Änderung) tun, führt dies zu einer unnötigen Blockierung des Hauptthreads und erhöht die Wahrscheinlichkeit von Schreibfehlern. In einigen Fällen reagiert der Browser-Tab sogar nicht mehr.

Anstatt den gesamten Statusbaum in einem einzelnen 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 Regel, die entweder ganz oder gar nicht gilt. In Fällen, in denen es nicht möglich ist, ein Zustandsobjekt aufzuteilen und nur den minimalen Änderungssatz zu schreiben, sollten die Daten in Unterstrukturen aufgeteilt werden, die nur geschrieben werden, um immer den gesamten Zustandsbaum zu schreiben. Kleine Verbesserungen sind besser als überhaupt keine.

Schließlich sollten Sie immer die Auswirkungen des von Ihnen geschriebenen Codes auf die Leistung messen. Es stimmt zwar, dass kleine Schreibvorgänge in IndexedDB eine bessere Leistung erzielen als große Schreibvorgänge, aber dies ist nur dann wichtig, wenn die Schreibvorgänge in IndexedDB, die Ihre Anwendung ausführt, tatsächlich zu langen Aufgaben führen, die den Hauptthread blockieren und die Nutzerfreundlichkeit beeinträchtigen. Es ist wichtig, die Leistung zu messen, damit Sie wissen, wofür Sie optimieren.

Ergebnisse

Entwickler können Clientspeichermechanismen wie IndexedDB verwenden, um die Nutzerfreundlichkeit ihrer Anwendung zu verbessern. Dazu wird der Status nicht nur über mehrere Sitzungen hinweg beibehalten, sondern auch die Zeit verkürzt, die zum Laden des ursprünglichen Status bei wiederholten Besuchen benötigt wird.

Die korrekte Verwendung von IndexedDB kann die Nutzerfreundlichkeit erheblich verbessern. Eine falsche Verwendung oder das Nichtbeheben von Fehlern kann jedoch zu instabilen 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äß behandelt werden, auch solche, die anfangs unwahrscheinlich erscheinen.