IndexedDB na prática: armazenamento de arquivos grandes e arquitetura offline no navegador

技术架构

Por que IndexedDB?

As opções de armazenamento do navegador têm limites claros cada uma:

Opção Capacidade Tipos de dados API síncrona Caso de uso
Cookie ~4KB String Identificadores de sessão
localStorage ~5MB String Configurações simples
sessionStorage ~5MB String Estado temporário
IndexedDB Centenas de MB–GB Quaisquer dados estruturados ❌ Async Arquivos grandes, apps offline

Para sites de ferramentas que precisam armazenar no navegador intermediários de processamento de PDF, módulos WASM ou o histórico de uploads dos usuários, o IndexedDB é a única opção viável.


Conceitos centrais

Banco de dados → Object Store → Registro

Database: "toolsku-cache"
  ├── ObjectStore: "wasm-modules"     (key: moduleName)
  ├── ObjectStore: "file-cache"       (key: fileHash, index: timestamp)
  └── ObjectStore: "user-preferences" (key: settingKey)

Transações e concorrência

As transações do IndexedDB são auto-confirmadas, e apenas uma transação de leitura/escrita por Object Store é permitida por vez:

const tx = db.transaction(['file-cache'], 'readwrite');
const store = tx.objectStore('file-cache');
await store.put({ hash: 'abc123', data: arrayBuffer, timestamp: Date.now() });
await tx.done; // Wait for transaction to complete

IndexedDB no ToolsKu

Cache de módulos WASM

O ffmpeg.wasm tem cerca de 30 MB e leva de 3 a 5 segundos para carregar cada vez. Após o cache no IndexedDB, as visitas seguintes são quase instantâneas:

async function getWasmModule(name: string): Promise<ArrayBuffer> {
  const cached = await idb.get('wasm-modules', name);
  if (cached) return cached;

  const response = await fetch(`/wasm/${name}.wasm`);
  const buffer = await response.arrayBuffer();
  await idb.put('wasm-modules', buffer, name);
  return buffer;
}

Armazenamento em fragmentos para arquivos grandes

Armazenar arquivos acima de 50 MB no IndexedDB de uma só vez não é ideal. Uma estratégia de fragmentação:

File (200MB) → split into 4MB chunks → store each in IndexedDB
key: "file:{hash}:chunk:{index}"
Read in order and concatenate → restore full file

Migração de versão

Quando o esquema do banco de dados muda, a migração é tratada em onupgradeneeded:

const request = indexedDB.open('toolsku-cache', 2); // version 2

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (event.oldVersion < 2) {
    db.createObjectStore('processing-history', { keyPath: 'id' });
  }
};

Boa prática: adicione apenas ObjectStores — nunca os remova. Incremente o número de versão para acionar a migração e evite excluir os dados dos usuários.


IndexedDB vs OPFS

Característica IndexedDB OPFS (Origin Private File System)
Maturidade da API Amplo suporte Chrome 86+ / Safari 15.2+
Modelo de leitura/escrita Armazenamento chave-valor Verdadeiro sistema de arquivos
Desempenho Moderado Maior (especialmente acesso síncrono)
Melhor para Cache estruturado E/S de arquivos grandes

O ToolsKu usa principalmente o IndexedDB, com o OPFS como otimização de desempenho no Chrome.


Resumo

O IndexedDB é infraestrutura essencial para ferramentas de navegador offline-first. Um bom design de Object Stores, o cache WASM e as estratégias de armazenamento em fragmentos permitem que o ToolsKu permaneça responsivo mesmo em redes lentas.

Experimente estas ferramentas executadas localmente no navegador — nenhum cadastro necessário →

#IndexedDB#浏览器存储#离线#大文件#架构