ワークボックスを使用した事前キャッシュ

Service Worker の機能の 1 つは、Service Worker のインストール時にファイルをキャッシュに保存できることです。これは「プリキャッシュ」と呼ばれます。プリキャッシュを使用すると、ネットワークにアクセスせずにキャッシュに保存されたファイルをブラウザに提供できます。オフラインでもサイトに必要な重要なアセット(メインページ、スタイル、代替画像、必須スクリプト)にはプリキャッシュを使用します。

Workbox によるプリキャッシュの使用は任意です。独自のコードを記述して、Service Worker のインストール時に重要なアセットをプリキャッシュできます。Workbox を使用する主なメリットは、すぐに使えるバージョン管理です。これらのファイルのバージョニングと更新を自分で管理するよりも、Workbox を使用してプリキャッシュ アセットを更新するほうが、はるかに問題が少なくなります。

マニフェストのプリキャッシュ

プリキャッシュは、URL のリストと各 URL に関連付けられたバージョニング情報によって駆動されます。これらの情報をまとめて、プリキャッシュ マニフェストと呼びます。マニフェストは、特定のバージョンのウェブアプリのプリキャッシュに含まれるすべての状態の「信頼できる情報源」です。Workbox で使用される形式のプリキャッシュ マニフェストは次のようになります。

[{
  url: 'app.abcd1234.js'
}, {
  url: 'offline.svg',
  revision: '7836745f'
}, {
  url: 'index.html',
  revision: '518747aa'
}]

サービス ワーカーがインストールされると、リストに表示された 3 つの URL ごとに、キャッシュ ストレージに 3 つのキャッシュ エントリが作成されます。最初のアセットには、URL にバージョニング情報がすでに含まれています(app は実際のファイル名で、.abcd1234 にはファイル拡張子 .js の直前にバージョニング情報が含まれています)。Workbox のビルドツールはこれを検出して、リビジョン フィールドを除外できます。他の 2 つのアセットの URL にはバージョニング情報は含まれていないため、Workbox のビルドツールは、ローカル ファイルの内容のハッシュを含む個別の revision フィールドを作成します。

プリキャッシュされたリソースの提供

アセットをキャッシュに追加することは、プリキャッシュの一部にすぎません。アセットがキャッシュに保存されたら、送信されるリクエストに応答する必要があります。これには、プリキャッシュされた URL を確認して、キャッシュに保存されたレスポンスを確実に返す Service Worker の fetch イベント リスナーが必要です。このプロセスではネットワークをバイパスします。Service Worker はキャッシュでレスポンスをチェックし(ネットワークよりも先に使用するため)、これをキャッシュ優先戦略と呼びます。

効率的な更新

プリキャッシュ マニフェストは、想定されるキャッシュ状態を正確に表します。マニフェストの URL とリビジョンの組み合わせが変更されると、サービス ワーカーは、以前のキャッシュに保存されたエントリが有効でなくなり、更新が必要であることを認識します。プリキャッシュされた URL の更新が必要な URL を判断するために必要なネットワーク リクエストは、サービス ワーカーの更新チェックの一環としてブラウザによって自動的に実行される 1 回だけです。

プリキャッシュ リソースの更新

ウェブアプリの新しいバージョンをリリースする際には、以前にプリキャッシュされた URL を最新の状態に保ち、新しいアセットをプリキャッシュし、古いエントリを削除する必要があります。サイトを再ビルドするたびに完全なプリキャッシュ マニフェストを生成し続ける場合、そのマニフェストは、任意の時点でのプリキャッシュ状態の「信頼できる情報源」として機能します。

新しいリビジョン フィールドを持つ既存の URL がある場合、またはマニフェストに URL が追加または削除されている場合は、install イベント ハンドラと activate イベント ハンドラの一部として、更新を実行する必要があることを Service Worker に通知します。たとえば、サイトに変更を加えて再ビルドした場合、最新のプリキャッシュ マニフェストには次のような変更が加えられている可能性があります。

[{
  url: 'app.ffaa4455.js'
}, {
  url: 'offline.svg',
  revision: '7836745f'
}, {
  url: 'index.html',
  revision: '518747aa'
}]

これらの変更のそれぞれは、以前にキャッシュに保存されたエントリ('offline.svg''index.html')を更新し、新しい URL をキャッシュに保存する('app.ffaa4455.js')、使用されなくなった URL を削除してクリーンアップする('app.abcd1234.js')ために、新しいリクエストを送信する必要があることをサービス ワーカーに通知します。

真の「アプリストア」インストール エクスペリエンス

プリキャッシュのもう 1 つのメリットは、「アプリストア」でのインストール以外では実現しにくいエクスペリエンスをユーザーに提供できることです。ユーザーがウェブアプリの任意のページに初めてアクセスしたときに、ウェブアプリの任意のビューを表示するために必要な URL をすべて事前にプリキャッシュに保存できます。これにより、ユーザーが各ビューにアクセスするまで待つ必要がなくなります。

ユーザーはアプリをインストールするときに、過去にアクセスしたビューだけでなく、すべての部分がすぐに表示されることを期待します。プリキャッシュを使用すると、ウェブアプリでも同じエクスペリエンスを実現できます。

どのアセットをプリキャッシュに保存すればよいか

プリキャッシュに最適な URL を把握するには、読み込まれている内容を特定するガイドを参照してください。一般的なルールとして、特定のページの基本構造を表示するために、早い段階で読み込まれ、重要な HTML、JavaScript、CSS をプリキャッシュに保存します。

メディアやその他のアセットをプリキャッシュに保存して後で読み込むことは避けてください(ウェブアプリの機能にとって不可欠な場合を除く)。代わりに、ランタイム キャッシュ戦略を使用して、これらのアセットがオンデマンドでキャッシュに保存されるようにします。

プリキャッシュには、アプリストアからアプリをインストールする場合と同様に、ユーザーのデバイスのネットワーク帯域幅とストレージの使用が伴うことを常に念頭に置いてください。適度にプリキャッシュし、プリキャッシュ マニフェストの肥大化を回避するのは、デベロッパーの責任です。

Workbox のビルドツールは、プリキャッシュ マニフェスト内のアイテムの数と、プリキャッシュ ペイロードの合計サイズを教えてくれるので便利です。

ウェブアプリに繰り返しアクセスするユーザーは、事前キャッシュの初期費用を長期的に回収できます。これは、ネットワークを回避できるため、時間の経過とともに帯域幅を節約できるためです。