Stockage pour le Web

Il existe de nombreuses options pour stocker des données dans le navigateur. Quelle option correspond le mieux à vos besoins ?

Les connexions Internet peuvent être instables ou inexistantes lors de vos déplacements, c'est pourquoi hors connexion et des performances fiables sont des fonctionnalités courantes applications Web progressives. Même en mode sans fil une utilisation judicieuse de la mise en cache et d'autres techniques de stockage améliorer considérablement l'expérience utilisateur. Il existe plusieurs façons de mettre en cache les ressources statiques de votre application (HTML, JavaScript, CSS, images, etc.) ; (données utilisateur, articles de presse, etc.). Mais quelle est la meilleure solution ? Comment quelle quantité pouvez-vous stocker ? Comment empêchez-vous son éviction ?

Que dois-je utiliser ?

Voici une recommandation générale pour le stockage des ressources:

IndexedDB et l'API Cache Storage sont compatibles avec tous les navigateurs modernes. Les deux sont asynchrones et ne bloquent pas le thread principal. Ils sont accessibles depuis l'objet window, les Web workers et les service workers, ce qui rend les rendre faciles à utiliser n'importe où dans votre code.

Qu'en est-il des autres mécanismes de stockage ?

Plusieurs autres mécanismes de stockage sont disponibles dans le navigateur, sont peu utilisés et peuvent entraîner d'importants problèmes de performances.

SessionStorage est spécifique à un onglet et s'applique au durée de vie de l'onglet. Il peut être utile de stocker de petites quantités des informations spécifiques, telles qu'une clé IndexedDB. Il doit être utilisé avec prudente, car il est synchrone et bloque le thread principal. Il est limitée à environ 5 Mo et ne peut contenir que des chaînes. Étant donné qu'il est spécifique à un onglet, il n'est pas accessible depuis les Web workers ni les service workers.

Évitez d'utiliser le stockage LocalStorage, car il est synchrone. et bloquera le thread principal. Elle est limitée à environ 5 Mo et peut contenir uniquement des chaînes. LocalStorage n'est pas accessible depuis les nœuds de calcul Web ou le service les nœuds de calcul.

Les cookies ont une utilité, mais ils ne doivent pas être utilisés pour le stockage. Des cookies sont envoyés avec chaque requête HTTP. Ainsi, le stockage d'éléments autres qu'un une petite quantité de données augmentera considérablement la taille de chaque requête Web. Ils sont synchrones et ne sont pas accessibles depuis les nœuds de calcul Web. J'aime LocalStorage et SessionStorage, les cookies sont limités aux chaînes uniquement.

L'API File System et l'API FileWriter fournissent des méthodes pour lire et écrire des fichiers dans un système de fichiers en bac à sable. Bien qu'il soit asynchrone, elle n'est pas recommandée, car elle uniquement disponible dans les navigateurs basés sur Chromium.

L'API File System Access a été conçue pour faciliter facile pour les utilisateurs de lire et de modifier des fichiers sur leur système de fichiers local. L'utilisateur doit accorder une autorisation pour qu'une page puisse lire ou écrire dans un fichier local ; et les autorisations ne sont pas conservées d'une session à l'autre.

WebSQL ne doit pas être utilisé, et l'utilisation existante doit être migrée vers Base de données indexée. L'assistance a été supprimée de presque tous les principaux des navigateurs. Le W3C a cessé de gérer la spécification Web SQL en 2010, sans aucune autre mise à jour prévue.

Le cache d'application ne doit pas être utilisé, tandis que l'utilisation existante doit être migrés vers les service workers et l'API Cache. Il a été obsolète et ne sera plus prise en charge dans les navigateurs dans à l'avenir.

Combien puis-je stocker ?

En bref, beaucoup, au moins quelques centaines de mégaoctets, et potentiellement des centaines de gigaoctets ou plus. Les implémentations de navigateur varient, mais la quantité disponible est généralement basé sur l'espace disponible sur le appareil.

  • Chrome permet au navigateur d'utiliser jusqu'à 80% de l'espace disque total. Une origine peut utilisent jusqu'à 60% de l'espace disque total. Vous pouvez utiliser la classe StorageManager API pour déterminer le quota maximal disponible. Autre les navigateurs peuvent être différents.
    • En mode navigation privée, Chrome réduit la quantité de stockage qu'une origine peut utiliser à environ 5% de l'espace disque total.
    • Si l'utilisateur a activé l'option "Effacer les cookies et les données des sites lorsque vous fermez fenêtres" dans Chrome, le quota de stockage est considérablement réduit, maximum d'environ 300 Mo.
    • Consultez le PR 3896 pour des détails sur l'implémentation de Chrome.
  • Internet Explorer 10 et versions ultérieures peuvent stocker jusqu'à 250 Mo et vous demandera l' un utilisateur lorsque plus de 10 Mo ont été utilisés.
  • Avec Firefox, le navigateur peut utiliser jusqu'à 50% de l'espace disque disponible. Une eTLD+1 groupe (par exemple, example.com, www.example.com et foo.bar.example.com) peut utiliser jusqu'à 2 Go. Vous pouvez utiliser API StorageManager pour déterminer l'espace restant disponibles.
  • Safari (ordinateur et mobile) semble permettre environ 1 Go. Lorsque la limite est atteinte, Safari va inviter l'utilisateur à augmenter la limite de 200 Mo par incréments. Je n'ai trouvé aucune documentation officielle à ce sujet.
    • Si une PWA est ajoutée à l'écran d'accueil de Safari pour mobile, elle apparaît Créer un conteneur de stockage, et rien n'est partagé entre la PWA et Safari pour mobile. Une fois le quota atteint pour une PWA installée, ne semble pas être un moyen de demander de l'espace de stockage supplémentaire.

Auparavant, si un site dépassait un certain seuil de données stockées, le navigateur demanderait à l'utilisateur d'accorder l'autorisation d’utiliser plus de données. Pour Par exemple, si l'origine était supérieure à 50 Mo, le navigateur affiche une invite pour lui permettre de stocker jusqu'à 100 Mo, puis redemandez par tranches de 50 Mo.

Aujourd'hui, la plupart des navigateurs récents n'invitent pas l'utilisateur et autorisent un site jusqu'au quota qui lui est alloué. L'exception semble être Safari, lorsque le quota de stockage est dépassé, vous demandant l'autorisation d'augmenter le quota alloué. Si une origine tente d'utiliser plus que le quota qui lui est alloué, les tentatives supplémentaires d'écriture de données échouera.

Comment vérifier l'espace de stockage disponible ?

Dans de nombreux navigateurs, vous pouvez utiliser le API StorageManager pour déterminer la quantité d'espace de stockage disponible pour l'origine et la quantité d'espace de stockage qu'il utilise. Il indique le total d'octets utilisés par IndexedDB et l'API Cache, ce qui permet pour calculer approximativement l'espace de stockage restant disponible.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

StorageManager n'est pas encore implemented dans tous les navigateurs. Vous devez donc doit la détecter avant de l'utiliser. Même lorsqu'elle est disponible, vous devez détecteront toujours les erreurs de dépassement de quota (voir ci-dessous). Dans certains cas, il est possible que le quota disponible pour dépasser la quantité réelle d'espace de stockage disponible.

Inspecter

Pendant le développement, vous pouvez utiliser les outils de développement de votre navigateur pour inspecter différents types de stockage et effacer facilement toutes les données stockées.

Une nouvelle fonctionnalité a été ajoutée dans Chrome 88 pour vous permettre d'ignorer l'espace de stockage du site dans le volet "Stockage". Cette fonctionnalité vous permet de simuler différents appareils et tester le comportement de vos applications en cas de faible disponibilité du disque. différents scénarios. Accédez à Application, puis à Stockage et activez l'option Simuler le quota de stockage personnalisé, puis saisissez un nombre valide pour et simuler le quota de stockage.

Volet "Stockage" des outils de développement

Alors que je travaillais sur cet article, j'ai créé un outil simple permettant de essayer d'utiliser rapidement autant de stockage que possible. C'est un moyen rapide et facile pour tester différents mécanismes de stockage vous utilisez tout votre quota.

Comment gérer le dépassement de quota ?

Que devez-vous faire lorsque vous dépassez le quota ? Plus important encore, vous devriez détecter et gérer toujours les erreurs d'écriture, qu'il s'agisse d'une QuotaExceededError ou autre chose. Ensuite, en fonction de la conception de votre application, déterminez comment la gérer. Par exemple, supprimez du contenu qui n'a pas été consulté depuis longtemps, des données en fonction de leur taille ou permettre aux utilisateurs de choisir ce qu'ils souhaitent supprimer.

La base de données IndexedDB et l'API Cache génèrent toutes deux une exception DOMError nommée QuotaExceededError lorsque vous avez dépassé le quota disponible.

IndexedDB

Si l'origine a dépassé son quota, les tentatives d'écriture dans IndexedDB échouer. Le gestionnaire onabort() de la transaction est appelé, en transmettant un événement. L'événement inclut un DOMException dans la propriété d'erreur. Vérification de la l'erreur name renvoie QuotaExceededError.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

API Cache

Si l'origine a dépassé son quota, tente d'écrire dans l'API Cache rejettera avec un DOMException QuotaExceededError.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

Comment fonctionne l'éviction ?

Le stockage Web est classé dans deux catégories : "Effort maximal" et "Persistant". L'optimisation consiste à vider l'espace de stockage interrompre l'utilisateur, mais est moins durable pour les données critiques ou à long terme. L'espace de stockage persistant n'est pas automatiquement effacé lorsque l'espace de stockage est faible. L'utilisateur doit effacer manuellement cet espace de stockage (via les paramètres du navigateur).

Par défaut, les données d'un site (y compris IndexedDB, Cache API, etc.) appartiennent à la catégorie d'optimisation, c'est-à-dire à moins qu'un site n'ait stockage persistant demandé, le navigateur peut évincer données du site à sa seule discrétion, par exemple lorsque l'espace de stockage de l'appareil est faible.

Pour éviter au mieux les situations, les règles d'éviction sont les suivantes:

  • Les navigateurs basés sur Chromium commenceront à évincer des données lorsque le navigateur sera épuisé en effaçant d'abord toutes les données du site depuis l'origine la moins récemment utilisée, puis le suivant, jusqu'à ce que le navigateur ne dépasse plus la limite.
  • Internet Explorer 10 ou version ultérieure n'évince pas les données, mais empêche l'origine de à écrire.
  • Firefox commencera à évincer les données lorsque l'espace disque disponible sera saturé, effacer d'abord toutes les données de site depuis l'origine la moins récemment utilisée, puis jusqu'à ce que le navigateur ne dépasse plus la limite.
  • Auparavant, Safari n'évince pas les données, mais a récemment mis en œuvre un nouveau limite de sept jours pour tout stockage accessible en écriture (voir ci-dessous).

À partir d'iOS, iPadOS 13.4 et Safari 13.1 sous macOS, il existe un limite de sept jours sur tout le stockage de script accessible en écriture, y compris IndexedDB, l'enregistrement du nœud de calcul et l'API Cache. Cela signifie que Safari évince tous les cache après sept jours d'utilisation dans Safari, si l'utilisateur n'a pas interagissent avec le site. Cette règle d'éviction ne s'applique pas aux applications PWA ajoutées à l'écran d'accueil. Voir Blocage complet des cookies tiers et plus encore sur WebKit pour plus d'informations.

Bonus: Pourquoi utiliser un wrapper pour IndexedDB ?

IndexedDB est une API de bas niveau qui nécessite une configuration importante avant utilisation. ce qui peut être particulièrement pénible pour stocker des données simples. Contrairement à la plupart des modèles sur la base de promesses, il est basé sur les événements. Promettez des wrappers tels que idb pour IndexedDB masque certaines des fonctionnalités puissantes, mais plus encore surtout de masquer les machines complexes (transactions, gestion des versions de schéma, etc.). qui est fourni avec la bibliothèque IndexedDB.

Conclusion

Fini le temps où l'espace de stockage était limité, et l'utilisateur était incité à stocker plus et plus de données. Les sites peuvent stocker efficacement toutes les ressources et données qu'ils à exécuter. L'API StorageManager vous permet d'effectuer les opérations suivantes : de déterminer la quantité dont vous disposez et celle que vous avez utilisée. Et avec stockage persistant, sauf si l'utilisateur le supprime, peut les protéger contre l'éviction.

Ressources supplémentaires

Merci

Nous remercions tout particulièrement Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink et Victor Costan pour avoir examiné cet article. Merci à Eiji Kitamura, Addy Osmani et Marc Cohen qui ont écrit les articles originaux sur lesquels cela se base. Eiji a écrit un outil utile appelée utilisation abusive du stockage sur le navigateur, qui nous a permis de valider le comportement actuel. Il vous permet de stocker autant de données que possible et de voir les limites de stockage de votre navigateur. Un grand merci à François Beaufort qui a fait ses recherches dans Safari pour déterminer ses limites de stockage.

L'image héros est de Guillaume Bolduc, Unsplash.