ネットワークの信頼性を確保するために、ブラウザの HTTP キャッシュは最初の防衛ラインですが、前述のように、以前にアクセスしたバージョニングされた URL を読み込む場合にのみ効果的です。HTTP キャッシュだけでは不十分です。
幸い、状況を好転させるために利用できる新しいツールが 2 つあります。サービス ワーカーと Cache Storage API です。これらは一緒に使用されることが多いので、両方を同時に学習することをおすすめします。
Service Worker
Service Worker はブラウザに組み込まれており、デベロッパーが作成する追加の JavaScript コードによって制御されます。これは、実際のウェブ アプリケーションを構成する他のファイルとともにデプロイします。
Service Worker には特別な権限があります。その他の機能として、ウェブアプリが送信リクエストを実行するのを辛抱強く待機し、リクエストをインターセプトして動作を開始します。Service Worker がこのインターセプトされたリクエストに対して行う処理は、任意です。
リクエストによっては、サービス ワーカーがまったく存在しない場合と同様に、リクエストをネットワークに転送することを許可するのが最善の方法となる場合があります。
ただし、他のリクエストの場合は、ブラウザの HTTP キャッシュよりも柔軟性の高いものを利用し、ネットワークを気にすることなく、信頼性の高い高速なレスポンスを返すことができます。これには、パズルのもう一方のピースである Cache Storage API を使用する必要があります。
Cache Storage API
Cache Storage API を使用すると、デベロッパーはキャッシュの内容を完全に制御できるため、まったく新しい可能性を切り開くことができます。Cache Storage API は、HTTP ヘッダーとブラウザの組み込みヒューリスティックを組み合わせるのではなく、キャッシュにコードドリブンなアプローチを公開します。Cache Storage API は、サービス ワーカーの JavaScript から呼び出す場合に特に便利です。
待って、別のキャッシュも考慮する必要があるのですか?
「HTTP ヘッダーを構成する必要があるか?」「この新しいキャッシュで HTTP キャッシュではできなかったことは何ですか?」などの疑問をお持ちかもしれません。心配はいりません。これは自然な反応です。
Cache Storage API を使用していることがわかっている場合でも、ウェブサーバーで Cache-Control
ヘッダーを構成することをおすすめします。通常は、バージョニングされていない URL には Cache-Control: no-cache
を設定します。また、ハッシュなどのバージョニング情報が含まれる URL には Cache-Control: max-age=31536000
を設定します。
Cache Storage API キャッシュにデータを入力する際、ブラウザは HTTP キャッシュで既存のエントリをデフォルトでチェックし、見つかったエントリを使用します。バージョン付きの URL を Cache Storage API キャッシュに追加すると、ブラウザは追加のネットワーク リクエストを回避できます。一方で、バージョンなしの URL に長いキャッシュ存続時間を指定するなど、Cache-Control
ヘッダーが正しく構成されていない場合、古いコンテンツが Cache Storage API に追加され、状況が悪化する可能性があります。Cache Storage API を効果的に使用するには、HTTP キャッシュの動作を整理することが前提条件となります。
この新しい API で可能になったことについて、答えは「たくさん」です。HTTP キャッシュだけでは困難または不可能な一般的な用途には、次のものがあります。
- キャッシュに保存されたコンテンツに対して「バックグラウンドで更新」アプローチ(stale-while-revalidate)を使用します。
- キャッシュに保存するアセットの最大数に上限を設定し、カスタム有効期限ポリシーを実装して、上限に達したアイテムを削除します。
- 以前にキャッシュに保存されたネットワーク レスポンスと新しいネットワーク レスポンスを比較して変更がないか確認し、データが実際に更新されたときにユーザーがコンテンツを更新できるようにします(ボタンなど)。
詳しくは、Cache API: クイックガイドをご覧ください。
API の詳細
API の設計には、次の点に注意してください。
- これらのキャッシュの読み取りと書き込みでは、
Request
オブジェクトが一意のキーとして使用されます。便利なように、実際のRequest
オブジェクトではなく、'https://example.com/index.html'
などの URL 文字列をキーとして渡すことができます。この場合、API によって自動的に処理されます。 - これらのキャッシュの値として
Response
オブジェクトが使用されます。 - データのキャッシュ保存時に、特定の
Response
のCache-Control
ヘッダーは無視されます。有効期限や更新頻度の自動チェックは組み込まれておらず、アイテムをキャッシュに保存すると、コードで明示的に削除されるまで保持されます。(キャッシュのメンテナンス作業を簡素化するライブラリがあります。これらについては、このシリーズの後半で説明します)。 LocalStorage
などの古い同期 API とは異なり、Cache Storage API のオペレーションはすべて非同期です。
ちょっとした脱線: Promise と async/await
サービス ワーカーと Cache Storage API は、非同期プログラミングのコンセプトを使用します。特に、非同期オペレーションの将来の結果を表すために、Promise に大きく依存しています。始める前に、Promise と関連する async
/await
構文をよく理解しておく必要があります。
まだそのコードをデプロイしないでください
サービス ワーカーと Cache Storage API は重要な基盤を提供し、そのまま使用できますが、どちらも実質的にはローレベルの構成要素であり、多くのエッジケースと「落とし穴」があります。これらの API の難しい部分をスムーズに処理し、本番環境対応のサービス ワーカーを構築するために必要なものをすべて提供する、より高度なツールがいくつかあります。次のガイドでは、そのようなツールの 1 つである Workbox について説明します。