Workbox を使用したランタイム キャッシュ

ランタイム キャッシュとは、キャッシュに「徐々に」レスポンスを追加することを意味します。ランタイム キャッシュは、現在のリクエストの信頼性には役立ちませんが、同じ URL に対する将来のリクエストの信頼性を向上させるのに役立ちます。

ブラウザの HTTP キャッシュはランタイム キャッシュの一例です。指定された URL のリクエスト後にのみデータが入力されます。ただし、Service Worker を使用すると、HTTP キャッシュのみで提供される機能を超えるランタイム キャッシュを実装できます。

戦略の策定

常にキャッシュから事前定義されたファイルのセットを提供しようとするプレキャッシュとは対照的に、ランタイム キャッシュでは、ネットワークとキャッシュ アクセスを複数の方法で組み合わせることができます。各組み合わせは一般に「キャッシュ戦略」と呼ばれます。主なキャッシュ戦略は次のとおりです。

  • ネットワーク ファースト
  • キャッシュ ファースト
  • 最新でない再検証

ネットワーク ファースト

このアプローチでは、Service Worker はまずネットワークからレスポンスを取得しようとします。ネットワーク リクエストが成功したら、レスポンスはウェブアプリに返され、Cache Storage API を使用してレスポンスのコピーが保存されます。このコピーは、新しいエントリを作成するか、同じ URL の以前のエントリを更新することで保存されます。

ページから Service Worker に送信されるリクエストと、Service Worker からネットワークに送信されるリクエストを示す図。ネットワーク リクエストが失敗するため、リクエストはキャッシュに移動します。

ネットワーク リクエストが完全に失敗した場合や、レスポンスを返すのに時間がかかりすぎる場合は、代わりにキャッシュから最新のレスポンスが返されます。

キャッシュ ファースト

キャッシュ ファースト戦略は、実質的にネットワーク ファーストとは正反対です。このアプローチでは、Service Worker がリクエストをインターセプトすると、まず Cache Storage API を使用して、キャッシュに保存されたレスポンスが使用可能かどうかを確認します。存在する場合、そのレスポンスはウェブアプリに返されます。

キャッシュミスが発生した場合、Service Worker はネットワークに移動してレスポンスを取得しようとします。ネットワーク リクエストが正常に終了すると、リクエストがウェブアプリに返され、キャッシュにコピーが保存されます。このキャッシュに保存されたコピーは、次回同じ URL がリクエストされたときにネットワークをバイパスするために使用されます。

ページから Service Worker に送信されるリクエストと、Service Worker からキャッシュに送信されるリクエストを示す図。キャッシュ リクエストが失敗するため、リクエストはネットワークに送信されます。

最新でない再検証

最新でない再検証はハイブリッドです。これを使用すると、Service Worker はキャッシュに保存されたレスポンスをすぐに確認し、見つかった場合はウェブアプリに返します。

その間に、キャッシュが一致したかどうかにかかわらず、Service Worker はネットワーク リクエストを発行して「新鮮な」レスポンスを返します。このレスポンスは、以前にキャッシュに保存されたレスポンスを更新するために使用されます。最初のキャッシュ チェックがミスだった場合は、ネットワーク レスポンスのコピーもウェブアプリに返されます。

ページから Service Worker に送信されるリクエストと、Service Worker からキャッシュに送信されるリクエストを示す図。キャッシュは即座にレスポンスを返し、同時に今後のリクエストのためにネットワークから更新をフェッチします。

Workbox を使用する理由

このようなキャッシュ戦略は、通常は独自の Service Worker で何度もレシピを書き換える必要があるレシピの量になります。Workbox は、それに頼るのではなく、ストラテジー ライブラリの一部としてパッケージ化されたものであり、Service Worker にドロップできます。

Workbox はバージョニングにも対応しているため、キャッシュに保存されたエントリを自動的に期限切れにしたり、以前にキャッシュに保存されたエントリの更新が発生したときにウェブアプリに通知したりできます。

どのアセットをキャッシュに保存し、どの戦略でキャッシュに保存しますか。

ランタイム キャッシュはプレキャッシュを補完するものとみなすことができます。すべてのアセットがすでに事前キャッシュされている場合は、作業は完了です。実行時にキャッシュに保存する必要は何もありません。ただし、比較的複雑なウェブアプリの場合、すべてを事前にキャッシュに保存することはおそらくないでしょう。

サイズの大きいメディア ファイル、CDN などのサードパーティ ホストから配信されるアセット、API レスポンスは、効果的に事前キャッシュできない種類のアセットのほんの一例です。DevTools の [Network] パネルを使用して、このカテゴリに該当するリクエストを特定し、それぞれについて、鮮度と信頼性のトレードオフについて検討します。

stale-while-revalidate を使用して、鮮度よりも信頼性を優先する

stale-while-revalidate 戦略では、最初のリクエストによってキャッシュにデータが挿入された後、ほぼ直ちにキャッシュに保存されたレスポンスが返されるため、この戦略を使用すると確実に高速なパフォーマンスが得られます。これには、ネットワークから取得されたものと比較して古いレスポンス データが返されるというトレードオフが伴います。この戦略は、ユーザーのプロファイル画像などのアセットや、ビューへの最初の入力に使用される API レスポンスの初期段階で、値が古い場合でもすぐに表示することが重要である場合に最適です。

ネットワーク ファーストを使用して、信頼性よりも鮮度を優先する

ある意味、ネットワーク ファーストの戦略を採用することは、ネットワークに対する戦いの失敗を認めることを意味します。優先順位は与えられていますが、信頼性に関する不確実性を伴います。特定のタイプのアセットでは、古い情報を返すよりも新しいレスポンスが返されることが推奨されます。たとえば、頻繁に更新される記事のテキストに対して API リクエストを行うときには、鮮度が望ましい場合があります。

Service Worker 内でネットワーク ファーストの戦略を使用することで、ネットワークに直接接続するだけでなく、レスポンスが古くても、なんらかのフォールバックできるというメリットがあります。速度は信頼性に欠けますが、オフライン時の信頼性は確保されます。

バージョン管理された URL にキャッシュ ファーストを使用する

キャッシュ ファースト戦略では、一度キャッシュに保存されたエントリは更新されません。そのため、変更される可能性が低いとわかっているアセットでのみ使用してください。特に、バージョニング情報を含む URL に最適です。このような URL は、Cache-Control: max-age=31536000 レスポンス ヘッダーでも配信する必要があります。