
IndexedDB – klientská database v prohlížeči
IndexedDB je nízkoúrovňové API pro ukládání velkého množství strukturovaných dat na straně klienta, včetně souborů a blobů.
IndexedDB je API prohlížeče pro ukládání velkého množství strukturovaných dat na straně klienta. Na rozdíl od localStorage umí pracovat s různými datovými typy (objekty, pole, bloby, soubory), podporuje indexy pro rychlé vyhledávání a celá práce s ní je asynchronní.
Kdy použít IndexedDB
- Ukládání dat pro offline režim (spolu se Service Workerem)
- Cachování dat z API pro rychlejší opakované načítání
- Ukládání velkých souborů a blobů (obrázky, PDF)
- Aplikace pracující s velkým objemem dat na klientu (e-mail klient, tabulkový editor)

Příklady z praxe
- E-mail klient (Gmail) – zprávy se ukládají lokálně, takže se zobrazí okamžitě i při pomalém připojení
- Projektové nástroje (Linear) – všechna data v IndexedDB, UI reaguje okamžitě bez čekání na server
- Kreslící nástroje (Figma, Excalidraw) – autosave rozdělané práce a offline přístup
- E-shopy – ukládání obsahu košíku, naposledy prohlížených produktů nebo filtrů
- Hry v prohlížeči – uložené posice, herní assety (textury, zvuky)
- Formuláře – automatické ukládání rozpracovaných formulářů, aby uživatel nepřišel o data při zavření stránky
Základní pojmy
- Database (
IDBDatabase) - Nejvyšší úroveň – každá aplikace si může vytvořit jednu nebo více databasí.
- Object store (
IDBObjectStore) - Obdoba tabulky v SQL – úložiště pro záznamy. Každý záznam má klíč a hodnotu.
- Index (
IDBIndex) - Umožňuje vyhledávat záznamy podle jiné vlastnosti než primárního klíče.
- Transakce (
IDBTransaction) - Veškerá práce s daty probíhá v rámci transakcí – buď se celá transakce povede, nebo se celá zruší.
- Kursor (
IDBCursor) - Slouží k procházení více záznamů v object store nebo indexu.
Otevření database
Database se otevírá s názvem a číslem verse. Pokud database neexistuje nebo je verse vyšší než aktuální, spustí se událost onupgradeneeded, kde se vytvářejí object stores a indexy:
var request = indexedDB.open('mojeDB', 1);
request.onupgradeneeded = function (event) {
var db = event.target.result;
// Vytvoření object store s autoincrement klíčem
var store = db.createObjectStore('kontakty', { keyPath: 'id', autoIncrement: true });
// Vytvoření indexu pro vyhledávání podle jména
store.createIndex('jmeno', 'jmeno', { unique: false });
};
request.onsuccess = function (event) {
var db = event.target.result;
console.log('Database otevřena', db);
};
request.onerror = function (event) {
console.error('Chyba při otevírání DB', event.target.error);
};
Zápis dat
Data se zapisují v rámci transakce s režimem readwrite:
var tx = db.transaction('kontakty', 'readwrite');
var store = tx.objectStore('kontakty');
store.add({ jmeno: 'Jan Novák', email: 'jan@example.com' });
store.add({ jmeno: 'Eva Svobodová', email: 'eva@example.com' });
tx.oncomplete = function () {
console.log('Data uložena');
};
Metoda add() vloží nový záznam (selže, pokud klíč již existuje). Metoda put() vloží nebo přepíše existující záznam.
Čtení dat
Čtení jednoho záznamu podle klíče:
var tx = db.transaction('kontakty', 'readonly');
var store = tx.objectStore('kontakty');
var request = store.get(1);
request.onsuccess = function () {
console.log('Kontakt:', request.result);
};
Vyhledávání přes index
Vyhledání záznamu podle indexovaného pole:
var tx = db.transaction('kontakty', 'readonly');
var store = tx.objectStore('kontakty');
var index = store.index('jmeno');
var request = index.get('Jan Novák');
request.onsuccess = function () {
console.log('Nalezeno:', request.result);
};
Procházení všech záznamů kursorem
var tx = db.transaction('kontakty', 'readonly');
var store = tx.objectStore('kontakty');
store.openCursor().onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log(cursor.key, cursor.value);
cursor.continue();
}
};
Mazání dat
var tx = db.transaction('kontakty', 'readwrite');
var store = tx.objectStore('kontakty');
// Smazání jednoho záznamu podle klíče
store.delete(1);
// Smazání všech záznamů
store.clear();
Versování database
Při změně struktury (přidání object store, nový index) se zvýší číslo verse. Prohlížeč pak spustí onupgradeneeded, kde lze provést migraci:
var request = indexedDB.open('mojeDB', 2);
request.onupgradeneeded = function (event) {
var db = event.target.result;
// Verse 1 → 2: přidání nového object store
if (!db.objectStoreNames.contains('poznamky')) {
db.createObjectStore('poznamky', { keyPath: 'id', autoIncrement: true });
}
};
localStorage vs. IndexedDB
| localStorage | IndexedDB | |
|---|---|---|
| Kapacita | ~5 MB | stovky MB i více |
| Datové typy | jen řetězce | objekty, pole, bloby |
| API | synchronní | asynchronní |
| Vyhledávání | jen podle klíče | indexy, kursory, rozsahy |
| Transakce | ne | ano |
Alternativa: SQLite WASM + OPFS
IndexedDB je klíč-hodnota úložiště – neumí relační dotazy (JOIN, GROUP BY, agregace). Pro složitější datové modely existuje alternativa: SQLite zkompilovaný do WebAssembly s persistencí přes Origin Private File System (OPFS).
Tuto cestu zvolil například Notion – původně používal IndexedDB, ale kvůli výkonnostním problémům přešel na SQLite WASM + OPFS. Nevýhodou je velikost WASM binary (~1 MB) a omezená podpora OPFS v některých prohlížečích.
Pro většinu webů je IndexedDB (ideálně přes knihovnu) jednodušší a dostačující. SQLite WASM se vyplatí až u aplikací s komplexním datovým modelem a velkým množstvím dotazů.
Knihovny
Nativní IndexedDB API je poměrně ukecaný. V praxi se často používají knihovny, které ho zjednodušují:
- idb – malý wrapper nad IndexedDB s Promise API od Jake Archibalda
- Dexie.js – populární knihovna s příjemným API a podporou versování
- Evolu – local-first knihovna postavená na SQLite WASM + OPFS s end-to-end šifrováním a CRDT synchronisací (nepoužívá IndexedDB)
Související odkazy
- MDN: IndexedDB API
- Can I Use… IndexedDB
Co si myslíte o tomto článku?
Diskuse
Související články
Service Worker – offline web, push notifikace a cache
Service Worker je skript běžící na pozadí prohlížeče, který umožňuje offline režim, push notifikace a pokročilé cachování webových stránek.
Offline stránka v PWA přes ServiceWorker
Jak udělat web fungující offline. A splnit tak požadavky na PWA.
Stažení dynamického webu
Jak stáhnout celou webovou stránku a převést ji do statické HTML podoby.