Moderní tvorba webových aplikací
O webu

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ů.

7 minut

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)

IndexedDB

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

localStorageIndexedDB
Kapacita~5 MBstovky MB i více
Datové typyjen řetězceobjekty, pole, bloby
APIsynchronníasynchronní
Vyhledáváníjen podle klíčeindexy, kursory, rozsahy
Transakceneano

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

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.

7 minut

Offline stránka v PWA přes ServiceWorker

Jak udělat web fungující offline. A splnit tak požadavky na PWA.

12 minut

Stažení dynamického webu

Jak stáhnout celou webovou stránku a převést ji do statické HTML podoby.

5 minut

Je uživatel online?

Jak zjistit, jestli je uživatel webové aplikace online nebo offline.

5 minut

Novinky e-mailem

Když budu mít něco opravdu zajímavého, můžu vám to poslat e-mailem

Přidej se k 500+ čtenářům
Jen kvalitní obsah
Žádný spam

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků · Témata · Zkratky
2013–2026