localStorage : limites et dépannage
Limites techniques
Section intitulée « Limites techniques »| Limite | Détail |
|---|---|
| Taille | Environ 5 Mo par origine (variable ; compté en caractères UTF-16) |
| Valeurs | Chaînes seulement |
| Accès | Synchrone : une grosse lecture ou écriture bloque l’interface |
| Contexte | Pas disponible dans un Web Worker ni un service worker |
| Requêtes | Aucune recherche : on lit une clé ou on parcourt tout |
| Transactions | Aucune : pas d’écriture atomique de plusieurs clés |
| Origine | Un stockage par origine, séparé entre http et https, entre sous-domaines et entre ports |
Dépasser ces limites : IndexedDB.
Quota dépassé
Section intitulée « Quota dépassé »try { localStorage.setItem('gros', 'x'.repeat(6 * 1024 * 1024));} catch (e) { if ( e instanceof DOMException && (e.name === 'QuotaExceededError' || e.code === 22) ) { console.warn('Stockage plein'); }}Conduite à tenir : libérer de la place (supprimer les anciennes données, un cache), prévenir l’utilisateur si une donnée importante n’a pas pu être enregistrée, et continuer à fonctionner sans le stockage.
Données effacées par le navigateur
Section intitulée « Données effacées par le navigateur »| Cause | Conséquence |
|---|---|
| L’utilisateur efface les données du site | Tout disparaît |
| Navigation privée | Stockage vidé à la fermeture de la fenêtre (et parfois en lecture seule ou de capacité très réduite) |
| Réglage « effacer les cookies et données à la fermeture » | Vidé à chaque fermeture |
| Manque d’espace disque | Le navigateur peut évincer des données de sites peu utilisés |
| Protection contre le suivi de certains navigateurs | Données de sites inutilisés pendant plusieurs jours supprimées |
Ne jamais compter sur la présence d’une donnée : prévoir la reconstruction (valeur par défaut, nouvelle synchronisation avec le serveur).
Demander un stockage durable
Section intitulée « Demander un stockage durable »L’API StorageManager permet de demander à ne pas être évincé et d’estimer l’espace :
if (navigator.storage?.persist) { const accorde = await navigator.storage.persist(); console.log('Stockage durable :', accorde);}
const { usage, quota } = await navigator.storage.estimate();console.log( `Utilisé : ${(usage / 1048576).toFixed(1)} Mo sur ${(quota / 1048576).toFixed(0)} Mo`,);Le navigateur décide d’accorder ou non la persistance (selon l’usage ou une interaction de l’utilisateur). estimate() concerne l’ensemble du stockage de l’origine (IndexedDB, caches…), pas seulement localStorage.
Détecter la disponibilité
Section intitulée « Détecter la disponibilité »export function stockageDisponible() { try { const test = '__test__'; localStorage.setItem(test, test); localStorage.removeItem(test); return true; } catch { return false; }}Utiliser cette fonction pour proposer un repli (mémoire, cookie) quand le stockage est indisponible.
const memoire = new Map();export const stockage = stockageDisponible() ? localStorage : { getItem: (c) => memoire.get(c) ?? null, setItem: (c, v) => void memoire.set(c, String(v)), removeItem: (c) => void memoire.delete(c), };Performances
Section intitulée « Performances »- Les accès sont synchrones : éviter les écritures dans une boucle serrée ou à chaque frappe de touche.
- Regrouper les écritures, ou les temporiser (anti-rebond) :
let minuteur;function sauvegarderBrouillon(texte) { clearTimeout(minuteur); minuteur = setTimeout(() => { try { localStorage.setItem('brouillon', texte); } catch {} }, 500);}- Ne pas stocker de très grosses chaînes (images en base64, longues listes) : chaque lecture parse tout.
- Lire une fois au démarrage, garder la valeur en mémoire, écrire à la modification.
Diagnostiquer
Section intitulée « Diagnostiquer »Outils de développement (F12) :
| Navigateur | Où |
|---|---|
| Firefox | Onglet Stockage > Stockage local |
| Chrome, Chromium, Edge | Onglet Application > Stockage local |
On peut y voir, modifier et supprimer les entrées, et vider le stockage du site (« Clear site data »).
// Lister avec les tailles, en consoleconsole.table( Object.entries(localStorage).map(([k, v]) => ({ cle: k, caracteres: v.length, })),);Surveiller les écritures pendant le débogage :
const original = Storage.prototype.setItem;Storage.prototype.setItem = function (cle, valeur) { console.log('setItem', cle, String(valeur).slice(0, 80)); return original.call(this, cle, valeur);};À retirer après le diagnostic.
Problèmes fréquents
Section intitulée « Problèmes fréquents »| Symptôme | Piste |
|---|---|
QuotaExceededError |
Stockage plein ou navigation privée : nettoyer, réduire, passer à IndexedDB |
| Les données ont disparu | Effacement par l’utilisateur, navigation privée, réglage du navigateur |
null alors que la valeur a été écrite |
Autre origine (http/https, www, port), autre profil, autre navigateur |
SecurityError à l’accès |
Données de sites bloquées, iframe avec sandbox, file:// selon le navigateur |
| Interface qui se fige | Écritures volumineuses et fréquentes : temporiser, réduire la taille |
| Deux onglets qui s’écrasent | Écritures non atomiques : clé par élément, navigator.locks |
Le stockage de localhost mélangé avec d’autres projets |
Même origine pour tous les projets sur le même port : préfixer les clés |
| Ancienne donnée qui fait planter la nouvelle version | Numéro de version et migration (voir JSON et structure des données) |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Aucune propre à Ubuntu. Le navigateur par défaut (Firefox, en paquet snap) et Chromium partagent les mêmes limites ; la capacité exacte varie selon le navigateur et sa version.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Quotas de stockage
- Retour : Introduction et API