Stephan Böni - Datenspeicher

Datenspeicher

Datenspeicher

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.

Web-Komponenten Listen

Javascript

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.

Javascript: default.js // Modules namespace const Modules = {}; Modules.coreReady = (async () => { // Dynamically import core modules const { WorkerProxy } = await import('./modules/workerProxy.js'); const { DataStore } = await import('./modules/dataStore.js'); // Create and initialize singleton instances Modules.workerProxy = new WorkerProxy(); await Modules.workerProxy.init(); Modules.dataStore = new DataStore({ webWorker: Modules.workerProxy }); })(); // Load module on demand Modules.loadModuleOnDemand = async function(selector, moduleName) { if (document.querySelector(selector)) { const filePath = `./modules/${moduleName.charAt(0).toLowerCase() + moduleName.slice(1)}.js`; await import(filePath); } }; document.addEventListener('DOMContentLoaded', async () => { await Modules.coreReady; Modules.loadModuleOnDemand('article-list', 'List'); }); Javascript: list.js this.#dataStore = Modules.dataStore; this.#dataStore.get({ store: 'indexeddb', pool: 'templates', key: templateName, fallbackStore: 'server' });

Ich sammle die Module im Unterordner modules und nenne die Dateien wie die Klasse, aber mit Kleinbuchstaben beginnend.

Du kannst dir die Klasse DataStore gerne herunterladen.

dataStore.js

Funktionsweise

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.

Web-Worker

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.

Web-Worker mit IndexedDB

Dran bleiben

Du hast es geschafft. Abonniere meine Benachrichtigungen, um weitere News und Anleitungen von mir zu erhalten.

Feed einbinden