使用可能な保存容量の見積もり

要約

今後さらに多くのブラウザが登場する Chrome 61 では、 ウェブアプリが使用しているストレージと、以下を介して利用可能な容量:

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

最新のウェブアプリとデータ ストレージ

最新のウェブ アプリケーションのストレージ ニーズについて考えると、 保存されるデータを 2 つのカテゴリに分ける: 読み込みに必要なコアデータ 重要なユーザー インタラクションに必要なデータだけを 表示されます。

1 つ目のデータタイプは ウェブアプリの読み込みに JavaScript、CSS、画像などですService Worker Cache Storage API コアリソースの節約に必要なインフラストラクチャを提供してから、 後でウェブアプリをすばやく読み込むこともできます。ネットワークを完全にバイパスするのが理想的です。 (新しい Workbox ライブラリまたは古い sw-precache、 保存、更新、使用のプロセスを 完全に自動化できます data.)

他のタイプのデータについてはどうでしょうか。これらのリソースは ウェブアプリの読み込みに時間がかかりますが、ユーザー全体にとって 体験できますたとえば、画像編集ウェブアプリを作成する場合は、 画像のローカルコピーを 1 つ以上保存して、ユーザーが 作業を元に戻すことができます。オフラインメディアや 音声や動画のファイルをローカルに保存することは非常に重要です。 機能。パーソナライズできるウェブアプリでは 一種の状態情報です。 では このタイプのランタイムストレージの空き容量は どうすればわかりますか? 空き容量がなくなるとどうなるでしょう

過去: window.webkitStorageInfonavigator.webkitTemporaryStorage

ブラウザはこれまで、接頭辞付きでこのタイプのイントロスペクションをサポートしてきました。 非常に古いインターフェース(非推奨)などの window.webkitStorageInfo 古いとは言えないものの、標準的ではない navigator.webkitTemporaryStorage。 これらのインターフェースは有用な情報を提供しましたが、 ウェブの標準として進化しています

WHATWG Storage Standard の 入ってきます

今後: navigator.storage

Storage Living Standard に関する継続的な取り組みの一環として、便利な API がいくつか公開されています。 それを StorageManager インターフェースです。このインターフェースは、 navigator.storage。 他の多くの新しいウェブ API と同様に、navigator.storage安全な接続でのみ使用できます。 (HTTPS または localhost で配信)オリジンから提供します。

昨年導入された navigator.storage.persist() メソッドを使用すると、ウェブ アプリケーションから、 除外されます

現在は navigator.storage.estimate() メソッドで結合されています。これは、 navigator.webkitTemporaryStorage.queryUsageAndQuota() の最新型。 estimate() は同様の情報を返しますが、 Promise ベースのインターフェースを使用して、 これは他の最新の非同期 API と整合します。この約束は、 estimate() は、usage と 現在使用されているバイト数を表す quota と 現在のバケットに格納できる最大バイト数 origin。 (ストレージに関連する他のあらゆるものと同様に、割り当てはプロジェクト全体に適用されます) origin.)

ウェブ アプリケーションが IndexedDB や Cache Storage API - 特定の送信元をその送信元に転送するのに十分な大きさのデータ 割り当てられている場合は、リクエストが失敗して QuotaExceededError 発生します。

保存容量の見積もりの実例

estimate() の正確な使用方法は、アプリが必要とするデータの種類によって異なります。 ありますたとえば、インターフェースのコントロールを更新し、ユーザーが 各ストレージ オペレーションが完了した後に使用されている容量を把握する。 その後、ユーザーが手動でデータをクリーンアップできるインターフェースを提供することが理想的です。 不要になりました次のような行に沿ってコードを記述できます。

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

推定はどの程度正確ですか?

重要な点として、関数から返されるデータは オリジンが使用しているスペースの推定値。関数内にあります。 名前です!usage 値も quota 値も安定していることは意図されていないため、 次の点を考慮することをおすすめします。

  • usage は、特定の送信元が効果的に使用しているバイト数を反映します。 same-origin です。 内部の圧縮技術の影響を受ける可能性があるため、 未使用領域が含まれる可能性がある固定サイズの割り振りブロックと、 「tombstone」をレコード 削除後に一時的に作成される場合もあります。データの漏えいを防ぐために 正確なサイズ情報、クロスオリジン、 不透明なリソース ローカルに保存すると、usage 全体に余分なパディング バイトが発生する可能性があります。 あります。
  • quota は、オリジンに現在予約されているスペースの量を表します。「 ストレージ全体のサイズなどの一定の要因によって変わりますが、 ストレージの容量など、不安定な可能性のある要因の数 使用されますデバイス上の他のアプリが ブラウザがウェブ用に割り当て可能なスペースの量 配信元が変更される可能性が高くなります。

現在: 機能の検出とフォールバック

Chrome 61 以降では、estimate() がデフォルトで有効になっています。Firefox は navigator.storage で試験運用されていますが、2017 年 8 月時点では更新されていません。 デフォルトで有効になっています。必要なこと dom.storageManager.enabled 設定を有効にする 必要があります。

一部のブラウザでまだサポートされていない機能を使用する場合は、 特徴量検出が必須です特徴検出機能とその他の機能を組み合わせて 古い navigator.webkitTemporaryStorage 上の Promise ベースのラッパー メソッドを使用し、次のような一貫したインターフェースを提供します。

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