Best Practices für die Verwendung von IndexedDB

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

Wenn ein Nutzer eine Website oder App zum ersten Mal lädt, ist der Aufwand Erstellung des anfänglichen Anwendungsstatus, der zum Rendern der UI verwendet wird. Manchmal wird zum Beispiel App muss den Nutzer clientseitig authentifizieren und dann mehrere API-Anfragen senden, bevor alle welche Daten auf der Seite angezeigt werden müssen.

Anwendungsstatus speichern in IndexedDB eignet sich hervorragend, um die Ladezeit für wiederholte Besuche. Die App kann dann im Hintergrund mit allen API-Diensten synchronisiert werden. und aktualisieren die UI nach und nach mit neuen Daten. stale-while- revalidation verwenden.

IndexedDB eignet sich auch gut zum Speichern von nutzergenerierten Inhalten, entweder als temporärer Speicher. bevor sie auf den Server hochgeladen werden, oder als clientseitiger Cache für Remotedaten – oder natürlich beides.

Bei der Verwendung von IndexedDB gibt es jedoch viele wichtige Aspekte zu berücksichtigen, die möglicherweise für Entwickler, die mit den APIs noch nicht vertraut sind. In diesem Artikel finden Sie Antworten auf häufig gestellte Fragen und werden einige der wichtigsten Aspekte erläutert, die bei der Speicherung von Daten in IndexedDB zu beachten sind.

Die App vorhersehbar gestalten

IndexedDB ist sehr komplex, weil es so viele Faktoren gibt, (der Entwickler) keine Kontrolle darüber haben. In diesem Abschnitt werden viele der Punkte behandelt, die Sie berücksichtigen müssen. wenn Sie mit IndexedDB arbeiten.

Nicht alles kann in IndexedDB auf allen Plattformen gespeichert werden

Wenn Sie große, von Nutzern erstellte Dateien wie Bilder oder Videos speichern, sollten Sie versuchen, sie als File- oder Blob-Objekte an. Dies funktioniert auf einigen Plattformen, auf anderen jedoch nicht. Safari an Insbesondere iOS kann Blobs nicht in IndexedDB speichern.

Zum Glück ist es nicht allzu schwierig, einen Blob in einen ArrayBuffer umzuwandeln und umgekehrt. Wird gespeichert ArrayBuffer-Objekte in IndexedDB werden sehr gut unterstützt.

Denken Sie jedoch daran, dass Blob einen MIME-Typ hat, ArrayBuffer jedoch nicht. Erforderliche Schritte den Typ zusammen mit dem Zwischenspeicher speichern, damit die Konvertierung ordnungsgemäß erfolgt.

Zum Konvertieren eines ArrayBuffer-Objekts in ein Blob-Objekt verwenden Sie einfach den Konstruktor Blob.

function arrayBufferToBlob(buffer, type) {
  return new Blob([buffer], { type: type });
}

Die andere Richtung ist etwas komplizierter und ein asynchroner Prozess. Sie können einen FileReader-Objekt, um das Blob als ArrayBuffer zu lesen. Nach dem Lesen wird ein loadend wird am Lesegerät ausgelöst. Sie können diesen Prozess so in einem Promise zusammenfassen:

function blobToArrayBuffer(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener('loadend', () => {
      resolve(reader.result);
    });
    reader.addEventListener('error', reject);
    reader.readAsArrayBuffer(blob);
  });
}

Fehler beim Schreiben in den Speicher

Fehler beim Schreiben in IndexedDB können aus verschiedenen Gründen auftreten. In einigen Fällen sind diese liegen außerhalb Ihrer Kontrolle als Entwickler. Beispielsweise ist in einigen Browsern Schreiben in IndexedDB im Modus für privates Surfen Es ist auch möglich, dass ein Nutzer ein Gerät verwendet, auf dem fast kein Speicherplatz mehr verfügbar ist, und der verhindert, dass Sie überhaupt etwas speichern.

Aus diesem Grund ist es von entscheidender Bedeutung, dass Sie in Ihren IndexedDB-Code. Dies bedeutet auch, dass es generell eine gute Idee ist, den Anwendungsstatus im Arbeitsspeicher (in damit die UI nicht abbricht, wenn sie im privaten Surfmodus ausgeführt wird ist kein Speicherplatz verfügbar (auch wenn einige andere App-Funktionen, die Speicherplatz erfordern, Arbeit).

Sie können Fehler bei IndexedDB-Vorgängen abfangen, indem Sie einen Event-Handler für das error-Ereignis hinzufügen immer wenn Sie ein IDBDatabase-, IDBTransaction- oder IDBRequest-Objekt erstellen.

const request = db.open('example-db', 1);
request.addEventListener('error', (event) => {
  console.log('Request error:', request.error);
};

Gespeicherte Daten wurden möglicherweise vom Nutzer geändert oder gelöscht

Im Gegensatz zu serverseitigen Datenbanken, bei denen Sie nicht autorisierten Zugriff einschränken können, sind clientseitige Datenbanken Browsererweiterungen und Entwicklertools zugänglich sind und vom Nutzer gelöscht werden können.

Es ist zwar ungewöhnlich, dass Nutzer ihre lokal gespeicherten Daten ändern, es kommt jedoch recht häufig vor, um sie zu löschen. Es ist wichtig, dass Ihre Anwendung beide Fälle fehlerfrei verarbeiten kann.

Gespeicherte Daten sind möglicherweise veraltet

Auch wenn der Nutzer die Daten selbst nicht geändert hat, Möglicherweise wurden die darin gespeicherten Daten von einer alten Version Ihres Codes geschrieben, möglicherweise Version mit Fehlern enthält.

IndexedDB unterstützt Schemaversionen und ein Upgrade über die IDBOpenDBRequest.onupgradeneeded() . Sie müssen Ihren Upgrade-Code jedoch trotzdem so schreiben, dass er den Nutzer verarbeiten kann, die aus einer früheren Version stammen (einschließlich einer Version mit einem Fehler).

Einheitentests können hier sehr hilfreich sein, da es oft nicht möglich ist, alle möglichen Tests manuell zu testen. Umstellungspfade und -fälle.

Leistung der App aufrechterhalten

Eines der wichtigsten Merkmale von IndexedDB ist das asynchrone API. Aber lassen Sie sich davon nicht täuschen. Sie müssen sich dabei keine Gedanken über die Leistung machen. Es gibt eine Reihe von Fällen, in denen Eine unsachgemäße Verwendung kann dennoch den Hauptthread blockieren, was zu Verzögerungen und einer Reaktionsfähigkeit führen kann.

Grundsätzlich sollten Lese- und Schreibvorgänge in IndexedDB nicht größer sein als der für die Daten erforderliche Wert. auf die zugegriffen wird.

IndexedDB ermöglicht es zwar, große, verschachtelte Objekte in einem einzigen Datensatz zu speichern. Aus Sicht von Entwickelnden zugegebenermaßen praktisch.) Diese Vorgehensweise sollte vermieden werden. Die Grund: Wenn IndexedDB ein Objekt speichert, muss zuerst ein strukturierter Klon und der strukturierte Klonvorgang erfolgt im Hauptthread. Je größer die umso länger ist die Blockierzeit.

Dies bringt einige Herausforderungen bei der Planung der Beibehaltung des Anwendungsstatus in IndexedDB mit sich, da die meisten der beliebten State Management-Bibliotheken (z. B. Redux) nutzen, Gesamtstruktur des Zustands als einzelnes JavaScript-Objekt.

Diese Art der Statusverwaltung hat viele Vorteile (z.B. wird Ihr Code einfacher nachvollziehbar und leicht zu verstehen, Debug) und das einfache Speichern des gesamten Zustandsbaums als einzelner Datensatz in IndexedDB verlockend und bequem zu gestalten, führt dies nach jeder Änderung zu einer unnötige Blockierung des Hauptthreads, erhöht dies die Wahrscheinlichkeit von Schreibfehlern. kann das sogar dazu führen, dass der Browsertab abstürzt oder nicht mehr reagiert.

Anstatt den gesamten Zustandsbaum in einem einzigen Datensatz zu speichern, sollten Sie ihn in einzelne und aktualisieren nur die Datensätze, die sich tatsächlich ändern.

Dasselbe gilt, wenn Sie große Elemente wie Bilder, Musik oder Videos in IndexedDB speichern. Einzelne Artikel speichern mit einem eigenen Schlüssel anstatt in einem größeren Objekt, sodass Sie die strukturierten Daten ohne auch die Kosten für das Abrufen der Binärdatei zu zahlen.

Wie bei den meisten Best Practices gilt auch hier keine Alles-oder-Nichts-Regel. Wenn es nicht möglich ist, ein Zustandsobjekt auflösen und nur den minimalen Änderungssatz schreiben, wobei die Daten in Unterstrukturen aufgeteilt werden Es ist immer noch besser, nur diese zu schreiben, als immer den gesamten Zustandsbaum zu schreiben. Wenig besser als gar keine Verbesserungen.

Außerdem sollten Sie immer die Auswirkungen auf die Leistung messen. des Codes, den Sie schreiben. Es stimmt, dass kleine Schreibvorgänge in IndexedDB besser funktionieren als große. geschrieben werden, ist dies nur wichtig, wenn die Schreibvorgänge in IndexedDB, die Ihre Anwendung durchführt, tatsächlich zu lange Aufgaben die den Hauptthread blockieren und die Nutzererfahrung beeinträchtigen. Es ist wichtig, zu messen, um zu verstehen, wofür Sie optimieren.

Ergebnisse

Entwickler können Client-Speichermechanismen wie IndexedDB nutzen, um ihre Anwendung nutzen, indem der Status nicht nur sitzungsübergreifend beibehalten wird, sondern auch die Zeit verkürzt wird, um bei wiederholten Besuchen den Ausgangszustand zu laden.

Die ordnungsgemäße Verwendung von IndexedDB kann die Nutzerfreundlichkeit erheblich verbessern. Wenn Sie Fehlerfälle nicht bearbeiten, kann dies zu defekten Apps und unzufriedenen Nutzern führen.

Da der Clientspeicher viele Faktoren umfasst, auf die Sie keinen Einfluss haben, ist es wichtig, dass Ihr Code getestet und verarbeitet Fehler korrekt, selbst solche, die ursprünglich unwahrscheinlich sind.