IndexedDB en pratique : stockage de fichiers volumineux et architecture hors ligne dans le navigateur

技术架构

Pourquoi IndexedDB ?

Les options de stockage du navigateur ont chacune des limites claires :

Option Capacité Types de données API synchrone Cas d'usage
Cookie ~4KB Chaîne Identifiants de session
localStorage ~5MB Chaîne Paramètres simples
sessionStorage ~5MB Chaîne État temporaire
IndexedDB Des centaines de Mo–Go Toutes données structurées ❌ Async Fichiers volumineux, apps hors ligne

Pour les sites d'outils qui doivent mettre en cache dans le navigateur les intermédiaires de traitement PDF, les modules WASM ou l'historique des téléversements des utilisateurs, IndexedDB est le seul choix viable.


Concepts centraux

Base de données → Object Store → Enregistrement

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

Transactions et concurrence

Les transactions IndexedDB sont auto-validées, et une seule transaction de lecture/écriture par Object Store est autorisée à la fois :

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 dans ToolsKu

Cache de modules WASM

ffmpeg.wasm fait environ 30 Mo et prend de 3 à 5 secondes à charger à chaque fois. Après la mise en cache dans IndexedDB, les visites suivantes sont quasi instantanées :

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;
}

Stockage fragmenté pour les fichiers volumineux

Stocker des fichiers de plus de 50 Mo dans IndexedDB en une seule fois n'est pas idéal. Une stratégie de fragmentage :

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

Migration de version

Lorsque le schéma de la base de données change, la migration est gérée dans 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' });
  }
};

Bonne pratique : ajoutez uniquement des ObjectStores — ne les supprimez jamais. Incrémentez le numéro de version pour déclencher la migration et évitez de supprimer les données utilisateur.


IndexedDB vs OPFS

Caractéristique IndexedDB OPFS (Origin Private File System)
Maturité de l'API Large prise en charge Chrome 86+ / Safari 15.2+
Modèle de lecture/écriture Magasin clé-valeur Véritable système de fichiers
Performances Modérées Plus élevées (accès synchrone surtout)
Idéal pour Cache structuré E/S de fichiers volumineux

ToolsKu utilise principalement IndexedDB, avec OPFS comme optimisation des performances sur Chrome.


Résumé

IndexedDB est une infrastructure essentielle pour les outils de navigateur offline-first. Une bonne conception d'Object Stores, le cache WASM et les stratégies de stockage fragmenté permettent à ToolsKu de rester réactif même sur les réseaux lents.

Essayez ces outils exécutés localement dans le navigateur — aucune inscription requise →

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