デバイスにデータを格納する

プログレッシブ Web Apps (PWA) には、ネットワーク接続が不安定になったりオフラインになったりした場合でも、ユーザーが作業を継続できるように、データをローカルに格納するための堅牢なオプションが用意されています。

PWA では、ローカル ストレージ、キャッシュ API、IndexedDB など、デバイスにデータを格納する方法がいくつかあります。

次の表では、さまざまなオプションについて説明します。この記事の残りの部分では、各オプションの詳細と使用シナリオについて説明します。

ストレージ オプション 説明
Web ストレージ Web Storage には、セッションとローカルの 2 種類があります。 Web Storage は、アプリのフロントエンド コードから少量のデータを格納する場合に便利です。 データはキーと値のペアとして構成され、現在のアプリの配信元でのみ使用できます。 セッション ストレージの場合、アプリが閉じられた場合や、ユーザーが同じウィンドウまたはタブで別の配信元を参照した場合など、セッションが終了するとデータがクリアされます。ローカル ストレージは、アプリがデータを削除するまで保持されます。
Indexeddb IndexedDB は、大量の構造化データを格納するための API です。 API は非同期であり、アプリのフロントエンド コードとサービス ワーカー コードの両方から使用できます。 IndexedDB API を使用して、クライアントに大量の構造化データ、または暗号化されたメディア オブジェクトやファイルなどのバイナリ データを格納します。
キャッシュ Cache API を使用して、キャッシュされたリソースを管理できます。 Cache API は Promise ベースであり、開発者は HTML、CSS、JavaScript、イメージ、JSON などの多くの Web リソースを格納および取得できます。 通常、Cache API はサービス ワーカーのコンテキスト内で使用されますが、アプリのフロントエンド コードでも使用できます。
ファイル システム アクセス ファイル システム アクセス API を使用すると、PWA はユーザーのデバイス上のファイルとフォルダーを読み取り、変更を元に戻すことができます。

: WebSQL またはアプリケーション キャッシュは使用しないでください。 これらは他の 2 つのブラウザー ストレージ メカニズムですが、どちらも非推奨になっています。 WebSQL の代わりに、IndexedDB を使用します。 アプリケーション キャッシュの代わりに、Cache API を使用します。

Web ストレージ

Web Storage は、ユーザーのデバイスに少量の文字列データを格納する場合に便利です。 Web Storage のキーと値のペア システムのシンプルさにより、使いやすくなります。

Web Storage は、アプリのメイン スレッドでのみ同期的に動作します。 つまり、Web Storage はサービス ワーカー内では使用できません。また、Web Storage を大量に使用すると、アプリケーションのパフォーマンスの問題が発生する可能性があります。

Web Storage、セッション、ローカルの各種類は、それを作成したドメインに分離された個別のデータ ストアとして維持されます。

  • sessionStorage はセッションの期間中のみ保持されます。たとえば、ブラウザーが開いている間(ページが更新されたときを含む)。
  • localStorage は、アプリ コード、ユーザー、またはブラウザーによってデータが削除されるまで保持されます。

次のコードは、 を使用 localStorageする方法を示しています。これは、使用方法 sessionStorage と似ています。

const browserInformation = {
  name: 'Microsoft Edge',
  version: 108
};

localStorage.setItem('browser', JSON.stringify(browserInformation));

上記のコードでは、 メソッドを使用して setItem() JavaScript オブジェクトを JSON 文字列localStorageとして格納し、 と等しいキーをbrowser割り当てます。 次に示すように、 メソッドを使用してから localStorage 情報を getItem() 取得できます。

const value = localStorage.getItem('browser');

const browserInformation = JSON.parse(value);

詳細については、「MDN の Web Storage API 」を参照してください。

Indexeddb

IndexedDB は、アプリのフロントエンド コードまたはサービス ワーカー コードで使用できる構造化データを格納するための非同期 API です。 クライアントに大量の構造化データ、または暗号化されたメディア オブジェクトやファイルなどのバイナリ データを格納するには、IndexedDB API を使用します。

IndexedDB は PWA にデータを格納するための最適なオプションです。API を使用すると、メイン スレッドをブロックしてもアプリの速度が低下せず、アプリのフロントエンド コードとサービス ワーカーの両方から使用できるためです。

IndexedDB の使用は Web Storage を使用するよりも複雑であり、データを格納するには次の手順が必要です。

  1. 関数を使用してデータベースを window.indexedDB.open() 開きます。
  2. 関数を使用して、データベースにオブジェクト ストアを作成します IDBDatabase.createObjectStore()
  3. 関数を使用して、データを格納するトランザクションを IDBDatabase.transaction() 開始します。
  4. イベントをリッスンして、操作が完了するまで待ちます。

コード例の詳細と表示については、「MDN での IndexedDB の使用 」を参照してください。

キャッシュ

Cache API は、アプリのフロントエンド コードまたはサービス ワーカーでネットワーク要求と応答を格納および取得するためのシステムです。 画像やファイルなどの資産をユーザーのデバイスにローカルに格納するために使用できます。 これにより、アプリケーションがオフラインの場合でも動作する場合や、アプリのレンダリングに必要なネットワーク要求の数を減らすことでパフォーマンスを向上させることができます。

次のコード スニペットは、サービス ワーカーでイベントを fetch リッスンし、キャッシュ API を使用してサーバーからの応答を格納する方法を示しています。

self.addEventListener("fetch", event => {
  async function cacheAndReturnRequest() {
    // Get the response from the server.
    const fetchResponse = await fetch(event.request.url);
    // Open the app's cache.
    const cache = await caches.open("cache-name");
    // Put the response in cache.
    cache.put(event.request.url, fetchResponse.clone());
    // And return the response.
    return fetchResponse.
  }

  event.respondWith(cacheAndReturnRequest());
});

他の便利なキャッシュ API シナリオを検出するには、「 Service Worker を使用してネットワーク要求を管理する」を参照してください。

ファイル システム アクセス

ファイル システム アクセス API を使用すると、ネイティブ アプリケーションに似た方法で、アプリがユーザーのデバイス上のファイルにアクセスできるようになります。 テキスト エディターやイメージ エディターなどのファイルの読み取りと書き込みを行うことができるアプリケーションを作成するために使用できます。

ユーザーのデバイスからファイルを開くには、 関数を使用します showOpenFilePicker()

openFileButton.addEventListener("click", async () => {
  const fileHandles = await window.showOpenFilePicker();
});

詳細については、MDN の Window.showOpenFilePicker() を参照してください。

また、ファイル システム アクセス API を PWA ファイル処理機能と組み合わせて、アプリを特定のファイルの種類のハンドラーとして登録できるため、ユーザーに対してよりネイティブな状態を感じることができます。 詳細については、「プログレッシブ Web Appsでファイルを処理する」を参照してください。

配信元とプライベートのファイル システム アクセス API は、ユーザーにより多くのプライバシーを提供することを目的としたファイル システム アクセス API のバリエーションです。 これにより、アプリケーションはユーザーのデバイス上のファイルにもアクセスできますが、アプリの配信元にプライベートな特定のディレクトリ内でのみアクセスできます。 また、この API は、ユーザーがエクスプローラーを使用してプライベート ディレクトリに簡単にアクセスできるようにするためのものではありません。

配信元とプライベートのファイル システムからファイルを開くには、Promise ベースの API を使用します navigator.storage

// Get the origin-private directory handle.
const root = await navigator.storage.getDirectory();
// Get the handle for a file in the directory.
const fileHandle = await root.getFileHandle("my-file.txt");

ストレージ クォータ

Microsoft Edge では、ローカル ストレージとセッション ストレージはそれぞれ約 5 MB に制限されています。

IndexedDB、Cache API、Origin プライベート ファイル システム アクセス API など、その他の種類のデータ ストレージでは、デバイスのディスク領域全体の最大 60% を使用できます。 たとえば、アプリが実行されているデバイスに 64 GB のディスクがある場合、Microsoft Edge では、アプリで最大約 38 GB のデータを格納できます。

デバイスで実際に使用できる空き領域は、60% のストレージ クォータ未満である可能性があることに注意してください。 たとえば、アプリが実行されているデバイスに 64 GB のディスクがあるが、オペレーティング システムやその他のファイルで 50 GB が既に使用されている場合、ストレージ クォータがまだ 38 GB であっても、アプリは 14 GB のデータのみを格納できます。

を使用 navigator.storage.estimate() して、アプリの配信元のストレージ クォータと、既に使用されているストレージ クォータの量を Storage Manager API に問い合わせることができます。 詳細については、MDN の StorageManager.estimate() を参照してください。

使用可能または許可されているデータを超えるデータを格納しようとすると、JavaScript エラーが発生します。 コードでは、ステートメントを使用してこのエラーを try...catch キャッチする必要があります。 次のコード スニペットは、Web Storage を使用してデータを格納するときに、クォータを超えたエラーをキャッチする方法を示しています。

try {
  localStorage.setItem('foo', 'bar');
} catch (e) {
  // Code that handles the lack of storage space.
}

データの削除

ユーザーのデバイスが使用可能なディスク領域 ( ストレージの負荷とも呼ばれます) で不足し始めると、Microsoft Edge は非永続的なデータの削除を開始します。

つまり、Cache API、IndexedDB、Origin Private File System Access API、または Web Storage を使用して格納されたデータが削除される可能性があります。

既定では、アプリストアのデータは永続的とは見なされず、ストレージの負荷が発生すると削除される可能性があります。 アプリが重要なデータを格納する場合は、 関数を navigator.storage.persist() 使用してアプリのストレージを永続的にします。 永続ストレージは、ユーザーのみがクリアできます。 詳細については、MDN の StorageManager.persist() に関するページを参照してください。