Die Verwaltung von Daten im Browser ist eine Herausforderung. Lokale Speicherungsmöglichkeiten wie Local- oder Session-Storage sind einfach zu implementieren, aber sie bieten keine ausreichende Leistung und Flexibilität für komplexe Anwendungen. Da kommt die IndexedDB zum Einsatz.
In diesem Beitrag stelle ich dir die universelle Klasse DataStore vor, mit der du Daten auf performante Weise im jeweils optimalsten Speicher hinterlegen und wieder auslesen kannst.
Welche Datenspeicher gibt es?
Local-Storage
Der Local-Storage ist ein einfacher Schlüssel-Wert-Speicher, der im Browser gespeichert wird. Er ist synchron und blockiert den Haupt-Thread. Der Local-Storage ist für kleine Datenmengen geeignet, die nicht häufig geändert werden. Der Local-Storage ist in der Regel langsamer als eine IndexedDB.
Session-Storage
Der Session-Storage ist ein Schlüssel-Wert-Speicher, der im Browser gespeichert wird. Er ist synchron und blockiert den Haupt-Thread. Der Session-Storage ist für kleine Datenmengen geeignet, die nur während einer Sitzung benötigt werden. Der Session-Storage ist in der Regel langsamer als eine IndexedDB.
IndexedDB
Eine IndexedDB ist eine Datenbank, die im Browser gespeichert wird. Sie ist eine NoSQL-Datenbank, die auf Objekte basiert. Die Datenbank ist in Transaktionen organisiert. Die Datenbank ist asynchron und wird im Hintergrund ausgeführt. Die Datenbank ist in der Regel schneller als eine SQL-Datenbank. Das Lesen und Schreiben von Daten in die Datenbank erfolgt über einen Web-Worker.
Cookies
Cookies sind kleine Textdateien, die im Browser gespeichert werden. Sie sind synchron und blockieren den Haupt-Thread. Cookies sind für kleine Datenmengen geeignet, die häufig geändert werden. Cookies sind in der Regel langsamer als eine IndexedDB.
Service Worker Cache
Der Service Worker Cache ist ein Dateispeicher, der im Browser gespeichert wird. Er ist asynchron und blockiert den Haupt-Thread nicht. Der Service Worker Cache ist für große Datenmengen geeignet, die nicht häufig geändert werden. Der Service Worker Cache wird vom Service Worker verwaltet und kann nicht direkt angesprochen werden.
Browser Cache
Der Browser Cache ist ein Dateispeicher, der im Browser gespeichert wird. Er ist asynchron und blockiert den Haupt-Thread nicht. Der Browser Cache ist für große Datenmengen geeignet, die nicht häufig geändert werden. Der Browser Cache wird automatisch vom Browser verwaltet und kann nicht direkt angesprochen werden.
Server
Der Server ist der ultimative und massgebliche Datenspeicher. Er ist für große Datenmengen geeignet, die häufig geändert werden. Der Server ist aber nicht lokal und daher in der Regel langsamer als alle anderen Datenspeicher.
Beispiel
Anhand der folgenden Liste kann die Verwendung von Datenspeichern aufgezeigt werden.
Die Daten werden aus einer JSON-Datei geladen und in der IndexedDB zwischengespeichert. Beim erneuten Laden der Seite werden die Daten aus der IndexedDB gelesen, was deutlich schneller ist als ein erneuter Serveraufruf.
Voraussetzungen
Das Konzept der Web-Komponenten sollte dir bekannt sein. Auch zur Funktionsweise der Liste gibt es bereits einen Beitrag.
Zur Kommunikation mit den verschiedenen Datenspeichern verwenden wir die Klasse DataStore. Diese Klasse wird in der default.js geladen und bei unserem Beispiel in der list.js verwendet.
Die Klasse DataStore ist eine zentrale Schnittstelle (ein sogenanntes "Facade-Pattern") für die Verwaltung von Daten in deiner Anwendung. Anstatt direkt mit localStorage, sessionStorage, IndexedDB oder dem Server zu kommunizieren, verwendest du diese Klasse. Sie abstrahiert die Komplexität der verschiedenen Speicherorte und bietet eine einheitliche und einfache API zum Abrufen (get) und Speichern (set) von Daten.
Ein Kernvorteil ist die Implementierung einer Caching-Strategie: Daten, die vom Server geholt werden, können automatisch in einem schnelleren lokalen Speicher (wie der IndexedDB) zwischengespeichert werden, um zukünftige Ladezeiten zu verkürzen.
Worker & IndexedDB
Die Interaktion mit der IndexedDB ist asynchron und kann die Performance deiner Anwendung beeinträchtigen. Um dies zu vermeiden, delegieren wir die Arbeit an einen Web-Worker. Der Web-Worker läuft in einem separaten Thread und kann so die Hauptausführung deiner Anwendung nicht blockieren.