Estimer l'espace de stockage disponible

Résumé

Chrome 61, avec d'autres navigateurs à venir, donne désormais une estimation de la quantité d'espace de stockage utilisé par une application Web et la quantité disponible via:

if ('storage' in navigator && 'estimate' in navigator.storage) {
  navigator.storage.estimate().then(({usage, quota}) => {
    console.log(`Using ${usage} out of ${quota} bytes.`);
  });
}

Applications Web modernes et stockage de données

Quand on pense aux besoins de stockage d'une application Web moderne, Il faut diviser ce qui est stocké en deux catégories: les données de base nécessaires au chargement l'application Web, et les données nécessaires à une interaction significative de l'utilisateur l'application est chargée.

Le premier type de données, c'est-à-dire les éléments nécessaires au chargement de votre application Web, du code JavaScript, du CSS et éventuellement des images. Les service workers, ainsi que l'API Cache Storage, fournir l'infrastructure nécessaire pour économiser ces ressources principales, puis utiliser pour charger rapidement votre application Web, idéalement en contournant complètement le réseau. (outils qui s'intègrent au processus de création de votre application Web, comme le nouveau Workbox ou versions antérieures sw-precache peut entièrement automatiser le processus de stockage, de mise à jour et d'utilisation de ce type data.)

Mais qu'en est-il de l'autre type de données ? Ce sont des ressources qui ne sont pas nécessaires pour pour charger votre application Web, mais qui peuvent jouer un rôle crucial expérience. Si vous écrivez une application Web de retouche d'images, par exemple, enregistrer une ou plusieurs copies locales d'une image, ce qui permet aux utilisateurs entre les révisions et d'annuler leur travail. Si vous développez un support hors connexion, l'expérience de lecture, l'enregistrement des fichiers audio ou vidéo en local . Chaque application Web pouvant être personnalisée finit par devoir économiser sorte d'informations sur l'état. Comment connaître l'espace disponible pour ce type de stockage d'exécution et que se passe-t-il lorsque vous manquez d'espace ?

Passée: window.webkitStorageInfo et navigator.webkitTemporaryStorage

Les navigateurs ont toujours accepté ce type d'introspection via des préfixes d'interface utilisateur, comme les très anciennes (et obsolètes) window.webkitStorageInfo, et "Pas exactement comme l'époque", mais qui n'est pas navigator.webkitTemporaryStorage Bien que ces interfaces fournissaient des informations utiles, elles n'ont pas en tant que normes du Web.

C'est là que la norme de stockage WHATWG entre dans l'image.

À venir: navigator.storage

Dans le cadre de notre travail continu sur Storage Living Standard, quelques API utiles ont apporté les modifications suivantes : au StorageManager qui est exposée aux navigateurs navigator.storage. Comme de nombreuses autres API Web plus récentes, navigator.storage n'est disponible que sur des plates-formes sécurisées. (diffusées via HTTPS ou localhost).

L'année dernière, nous avons lancé le navigator.storage.persist() , qui permet à votre application Web de demander que son espace de stockage exemptés du nettoyage automatique.

Il est maintenant joint par la méthode navigator.storage.estimate(), qui sert de de remplacement moderne de navigator.webkitTemporaryStorage.queryUsageAndQuota(). estimate() renvoie des informations similaires, mais expose une l'interface basée sur une promesse, ce qui est semblable à celui des autres API asynchrones modernes. La promesse que La fonction estimate() renvoie une résolution avec un objet contenant deux propriétés: usage, représentant le nombre d'octets actuellement utilisés et quota, qui représente le le nombre maximal d'octets pouvant être stockés origin (origine). (Comme pour tout ce qui concerne le stockage, le quota s'applique à l'intégralité origin.)

Si une application Web tente d'effectuer un stockage, par exemple à l'aide de IndexedDB ou du L'API Cache Storage, c'est-à-dire des données suffisamment volumineuses pour transférer une origine donnée sur son quota disponible, la requête échoue, et une erreur QuotaExceededError une exception.

Estimations de l'espace de stockage en action

La manière exacte dont vous utilisez estimate() dépend du type de données dont votre application a besoin Google Store. Par exemple, vous pouvez mettre à jour une commande dans votre interface pour permettre aux utilisateurs de connaître la quantité d'espace utilisée après chaque opération de stockage terminée. Idéalement, vous fourniriez ensuite une interface permettant aux utilisateurs de nettoyer manuellement les données. qui ne sont plus nécessaires. Vous pouvez écrire du code comme suit:

// For a primer on async/await, see
// https://developers.google.com/web/fundamentals/getting-started/primers/async-functions
async function storeDataAndUpdateUI(dataUrl) {
  // Pro-tip: The Cache Storage API is available outside of service workers!
  // See https://googlechrome.github.io/samples/service-worker/window-caches/
  const cache = await caches.open('data-cache');
  await cache.add(dataUrl);

  if ('storage' in navigator && 'estimate' in navigator.storage) {
    const {usage, quota} = await navigator.storage.estimate();
    const percentUsed = Math.round(usage / quota * 100);
    const usageInMib = Math.round(usage / (1024 * 1024));
    const quotaInMib = Math.round(quota / (1024 * 1024));

    const details = `${usageInMib} out of ${quotaInMib} MiB used (${percentUsed}%)`;

    // This assumes there's a <span id="storageEstimate"> or similar on the page.
    document.querySelector('#storageEstimate').innerText = details;
  }
}

Quel est le degré de précision de l'estimation ?

Il est difficile de passer à côté du fait que les données que vous obtenez en retour de la fonction sont simplement une estimation de l'espace qu'utilise une origine. Elle se trouve dans la fonction nom ! Les valeurs usage et quota n'ont pas vocation à être stables. Par conséquent, nous vous recommandons de tenir compte des éléments suivants:

  • usage reflète le nombre d'octets utilisés efficacement par une origine donnée même-origine de données, qui à leur tour peuvent être affectées par des techniques de compression interne des blocs d'allocation de taille fixe pouvant inclure de l'espace inutilisé et la présence de "tombstone" enregistrements pouvant être créés temporairement après une suppression. Pour éviter les fuites d'informations de taille exacte, multi-origines des ressources opaques enregistrés localement peuvent contribuer à ajouter des octets de marge intérieure à l'ensemble usage .
  • quota reflète la quantité d'espace actuellement réservée à une origine. La dépend de facteurs constants, comme la taille globale de l'espace de stockage, mais aussi Nombre de facteurs potentiellement volatils, y compris l'espace de stockage qui est actuellement inutilisé. Ainsi, lorsque d'autres applications d'un appareil écrivent ou suppriment la quantité d'espace que le navigateur est prêt à consacrer à votre site Web, l'origine de l'application changera probablement.

Le présent: détection des fonctionnalités et solutions de secours

estimate() est activé par défaut à partir de Chrome 61. Firefox est en testant navigator.storage. Toutefois, depuis août 2017, elle n'a pas été est activée par défaut. Vous devez activer la préférence dom.storageManager.enabled pour la tester.

Lorsque vous travaillez avec une fonctionnalité qui n'est pas encore prise en charge par tous les navigateurs, la détection de caractéristiques est indispensable. Vous pouvez combiner la détection de caractéristiques un wrapper basé sur une promesse en plus de l'ancien navigator.webkitTemporaryStorage pour fournir une interface cohérente comme suit:

function storageEstimateWrapper() {
  if ('storage' in navigator && 'estimate' in navigator.storage) {
    // We've got the real thing! Return its response.
    return navigator.storage.estimate();
  }

  if ('webkitTemporaryStorage' in navigator &&
      'queryUsageAndQuota' in navigator.webkitTemporaryStorage) {
    // Return a promise-based wrapper that will follow the expected interface.
    return new Promise(function(resolve, reject) {
      navigator.webkitTemporaryStorage.queryUsageAndQuota(
        function(usage, quota) {resolve({usage: usage, quota: quota})},
        reject
      );
    });
  }

  // If we can't estimate the values, return a Promise that resolves with NaN.
  return Promise.resolve({usage: NaN, quota: NaN});
}