サービス ワーカー キャッシュ レイヤと HTTP キャッシュ レイヤで、一貫した有効期限ロジックを使用するか、異なる有効期限ロジックを使用するかについてのメリットとデメリット。
サービス ワーカーと PWA が最新のウェブ アプリケーションの標準になりつつある一方で、リソース キャッシュはかつてないほど複雑になっています。この記事では、ブラウザのキャッシュの概要について説明します。
- サービス ワーカーのキャッシュと HTTP キャッシュのユースケースと違い。
- 通常の HTTP キャッシュ保存戦略と比較した場合、Service Worker のキャッシュ有効期限戦略のメリットとデメリット。
キャッシュ フローの概要
大まかに言えば、ブラウザはリソースをリクエストするときに、次のキャッシュ順序に従います。
- Service Worker キャッシュ: Service Worker は、リソースがキャッシュ内にあるかどうかを確認し、プログラムされたキャッシュ戦略に基づいてリソース自体を返すかどうかを決定します。なお、この処理は自動的には行われません。Service Worker でフェッチ イベント ハンドラを作成し、ネットワーク リクエストをインターセプトして、リクエストがネットワークではなく Service Worker のキャッシュから提供されるようにする必要があります。
- HTTP キャッシュ(ブラウザ キャッシュ): リソースが HTTP キャッシュにあり、有効期限が切れていない場合、ブラウザは HTTP キャッシュ内のリソースを自動的に使用します。
- サーバーサイド: Service Worker キャッシュまたは HTTP キャッシュに何も見つからない場合、ブラウザはネットワークにアクセスしてリソースをリクエストします。リソースが CDN にキャッシュされていない場合、リクエストは送信元サーバーにまで戻る必要があります。
キャッシュ レイヤ
Service Worker のキャッシュ
Service Worker は、ネットワーク タイプの HTTP リクエストをインターセプトし、キャッシュ戦略を使用して、ブラウザに返すリソースを決定します。Service Worker キャッシュと HTTP キャッシュの汎用的な目的は同じですが、Service Worker のキャッシュは、キャッシュの対象やキャッシュの実行方法をきめ細かく制御できるなど、より多くのキャッシュ機能を備えています。
Service Worker キャッシュの制御
サービス ワーカーは、イベント リスナー(通常は fetch
イベント)を使用して HTTP リクエストをインターセプトします。このコード スニペットは、キャッシュ ファーストのキャッシュ戦略のロジックを示しています。
一から作り直すことのないよう、Workbox を使用することを強くおすすめします。たとえば、1 行の正規表現コードでリソース URL パスを登録できます。
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('styles/.*\\.css'), callbackHandler);
Service Worker のキャッシュ保存戦略とユースケース
次の表に、一般的なサービス ワーカーのキャッシュ戦略と、各戦略が役立つ場合を示します。
対策 | 最新性の根拠 | ユースケース |
---|---|---|
ネットワークのみ | コンテンツは常に最新の状態にする必要があります。 |
|
ネットワークから取得できなければキャッシュから取得 | 新しいコンテンツを提供することが望ましい。ただし、ネットワークに障害が発生した場合やネットワークが不安定な場合は、少し古いコンテンツを配信してもかまいません。 |
|
Stale-while-revalidate | キャッシュに保存されたコンテンツをすぐに配信してもかまいませんが、今後は更新されたキャッシュに保存されたコンテンツを使用する必要があります。 |
|
キャッシュに保存してからネットワークにフォールバックする | コンテンツは重要ではなく、パフォーマンス向上のためにキャッシュから提供できますが、Service Worker は時々アップデートを確認する必要があります。 |
|
キャッシュのみ | コンテンツが変更される可能性はほとんどありません。 |
|
Service Worker のキャッシュ保存のその他のメリット
Service Worker のキャッシュは、キャッシュ ロジックのきめ細かい制御に加え、次の機能も提供します。
- オリジンのメモリとストレージ容量の増加: ブラウザは、HTTP キャッシュ リソースをオリジンごとに割り当てます。つまり、複数のサブドメインがある場合、それらはすべて同じ HTTP キャッシュを共有します。オリジン / ドメインのコンテンツが HTTP キャッシュに長時間保持されるとは限りません。たとえば、ユーザーがブラウザの設定 UI から手動でクリーンアップしたり、ページのハードリロードをトリガーしたりして、キャッシュを完全に削除できます。Service Worker のキャッシュを使用すると、キャッシュに保存されたコンテンツがキャッシュに保存されたままになる可能性がはるかに高くなります。詳細については、永続ストレージをご覧ください。
- 不安定なネットワークやオフライン エクスペリエンスでの柔軟性の向上: HTTP キャッシュでは、リソースをキャッシュに保存するか、キャッシュに保存しないかの 2 つの選択肢しかありません。サービス ワーカーのキャッシュを使用すると、小さな「ハプニング」を簡単に軽減できます(「再検証中の古いコンテンツ」戦略を使用)。また、完全なオフライン エクスペリエンスを提供することもできます(「キャッシュのみ」戦略を使用)。さらに、ページの一部をサービス ワーカー キャッシュから取得し、一部を除外するカスタマイズされた UI など、中間的な方法も使用できます(「キャッチ ハンドラを設定する」戦略を使用)。
HTTP キャッシュ
ブラウザがウェブページと関連リソースを初めて読み込むと、これらのリソースは HTTP キャッシュに保存されます。通常、HTTP キャッシュは、エンドユーザーが明示的に無効にしていない限り、ブラウザによって自動的に有効になります。
HTTP キャッシュを使用する場合、リソースをキャッシュするタイミングとキャッシュ保存時間をサーバーが決定します。
HTTP レスポンス ヘッダーで HTTP キャッシュの有効期限を制御する
サーバーがリソースのブラウザ リクエストに応答すると、サーバーは HTTP レスポンス ヘッダーを使用して、リソースをキャッシュに保存する期間をブラウザに伝えます。詳しくは、レスポンス ヘッダー: ウェブサーバーを構成するをご覧ください。
HTTP キャッシュ戦略とユースケース
HTTP キャッシュは、時間ベース(TTL)のリソースの有効期限ロジックのみを処理するため、Service Worker のキャッシュよりもはるかにシンプルです。HTTP キャッシュ戦略の詳細については、使用するレスポンス ヘッダーの値と概要をご覧ください。
キャッシュの有効期限ロジックの設計
このセクションでは、Service Worker のキャッシュ レイヤと HTTP キャッシュ レイヤで一貫した有効期限ロジックを使用するメリットとデメリットと、これらのレイヤで個別の有効期限ロジックを使用するメリットとデメリットについて説明します。
以下の Glitch は、さまざまなシナリオで Service Worker のキャッシュと HTTP キャッシュがどのように機能するかを示しています。
すべてのキャッシュ レイヤに一貫した有効期限ロジック
メリットとデメリットを説明するために、長期、中期、短期の 3 つのシナリオについて説明します。
シナリオ | 長期キャッシュ | 中期キャッシュ | 短期キャッシュ |
---|---|---|---|
Service Worker のキャッシュ戦略 | キャッシュ、ネットワークへのフォールバック | Stale-while-revalidate | ネットワークから取得できなければキャッシュから取得 |
サービス ワーカー キャッシュ TTL | 30 days | 1 日 | 10 分 |
HTTP キャッシュの max-age | 30 days | 1 日 | 10 分 |
シナリオ: 長期キャッシュ(キャッシュになければネットワークから取得)
- キャッシュに保存されたリソースが有効な場合(30 日以内): Service Worker はネットワークにアクセスせずに、キャッシュに保存されたリソースをすぐに返します。
- キャッシュに保存されたリソースの有効期限が切れた場合(30 日以上経過している場合): サービス ワーカーがネットワークにアクセスしてリソースを取得します。ブラウザの HTTP キャッシュにはリソースのコピーがないため、リソースはサーバーサイドで取得されます。
デメリット: このシナリオでは、Service Worker でキャッシュが期限切れになると、ブラウザは常にリクエストをサーバーサイドに渡すため、HTTP キャッシュの価値は低くなります。
シナリオ: 中期キャッシュ(再検証中ステイル)
- キャッシュに保存されたリソースが有効な場合(1 日以下): Service Worker はキャッシュに保存されたリソースをすぐに返します。その後、ネットワークにアクセスしてリソースを取得します。ブラウザは HTTP キャッシュにリソースのコピーを保持するため、そのコピーを Service Worker に返します。
- キャッシュに保存されたリソースが期限切れの場合(1 日以上経過している場合): サービス ワーカーはキャッシュに保存されたリソースをすぐに返します。その後、ネットワークにアクセスしてリソースを取得します。ブラウザの HTTP キャッシュにリソースのコピーがないため、サーバーサイドに移動してリソースを取得します。
デメリット: サービス ワーカーでは、「再検証」ステップを最大限に活用するために、HTTP キャッシュをオーバーライドする追加のキャッシュ破棄が必要です。
シナリオ: 短期キャッシュ保存(ネットワークから取得できなければキャッシュから取得)
- キャッシュに保存されたリソースが有効な場合(10 分以下): Service Worker はネットワークにアクセスしてリソースを取得します。ブラウザは HTTP キャッシュにリソースのコピーを保持するため、サーバー側でアクセスせずに Service Worker にリソースのコピーを返します。
- キャッシュに保存されたリソースの有効期限が切れている場合(10 分超): Service Worker はキャッシュに保存されたリソースをすぐに返します。そして、ネットワークにアクセスしてリソースを取得します。ブラウザの HTTP キャッシュにリソースのコピーがないため、サーバーサイドに移動してリソースを取得します。
短所: 中期キャッシュ シナリオと同様に、Service Worker では、サーバーサイドから最新のリソースを取得するために HTTP キャッシュをオーバーライドするキャッシュ破壊ロジックを追加する必要があります。
すべてのシナリオでのサービス ワーカー
どのシナリオでも、ネットワークが不安定な場合、Service Worker キャッシュはキャッシュに保存されたリソースを返すことができます。一方、ネットワークが不安定または停止している場合、HTTP キャッシュは信頼できません。
サービス ワーカー キャッシュと HTTP レイヤで異なるキャッシュ有効期限ロジック
長所と短所を示すために、長期、中期、短期のシナリオを再度見てみましょう。
シナリオ | 長期キャッシュ | 中期キャッシュ | 短期キャッシュ |
---|---|---|---|
Service Worker のキャッシュ戦略 | キャッシュ、ネットワークへのフォールバック | Stale-while-revalidate | ネットワークから取得できなければキャッシュから取得 |
サービス ワーカー キャッシュ TTL | 90 日間 | 30 days | 1 日 |
HTTP キャッシュの max-age | 30 days | 1 日 | 10 分 |
シナリオ: 長期キャッシュ保存(キャッシュ、ネットワークへのフォールバック)
- キャッシュに保存されたリソースが Service Worker キャッシュで有効な場合(90 日以内): Service Worker はキャッシュに保存されたリソースをすぐに返します。
- キャッシュに保存されたリソースが Service Worker キャッシュで期限切れになった場合(90 日間経過した場合): Service Worker はネットワークにアクセスしてリソースを取得します。ブラウザの HTTP キャッシュにはリソースのコピーがないため、ブラウザはサーバーサイドで転送されます。
長所と短所:
- 利点: サービス ワーカーがキャッシュに保存されたリソースをすぐに返すため、ユーザーは即座にレスポンスを得ることができます。
- 利点: サービス ワーカーでは、キャッシュを使用するタイミングと新しいバージョンのリソースをリクエストするタイミングをよりきめ細かく制御できます。
- デメリット: 明確な Service Worker のキャッシュ戦略が必要です。
シナリオ: 中期キャッシュ保存(Stale-while-revalidate)
- キャッシュに保存されたリソースが Service Worker キャッシュで有効な場合(30 日以内): Service Worker はキャッシュに保存されたリソースを直ちに返します。
- キャッシュに保存されたリソースがサービス ワーカー キャッシュで期限切れになった場合(30 日以上経過した場合): サービス ワーカーはネットワークにリソースを取得しに行きます。ブラウザの HTTP キャッシュにリソースのコピーがないため、サーバーサイドに移動します。
長所と短所:
- 利点: サービス ワーカーがキャッシュに保存されたリソースをすぐに返すため、ユーザーは即座にレスポンスを得ることができます。
- 利点: サービス ワーカーは、「バックグラウンド」で再検証を行うため、特定の URL に対する次回のリクエストでネットワークからの最新のレスポンスを使用できます。
- デメリット: 明確な Service Worker キャッシュ戦略が必要です。
シナリオ: 短期キャッシュ保存(ネットワークから取得できなければキャッシュから取得)
- キャッシュに保存されたリソースが Service Worker キャッシュで有効な場合(1 日以内): Service Worker はネットワークにアクセスしてリソースを取得します。ブラウザは、HTTP キャッシュ内にリソースがあれば、そこからリソースを返します。ネットワークがダウンすると、Service Worker は Service Worker のキャッシュからリソースを返します。
- キャッシュに保存されたリソースが Service Worker キャッシュで期限切れになった場合(1 日以上経過している場合): Service Worker はネットワークにアクセスしてリソースを取得します。HTTP キャッシュにキャッシュされたバージョンの有効期限が切れているため、ブラウザはネットワーク経由でリソースを取得します。
長所と短所:
- 利点: ネットワークが不安定または停止している場合、サービス ワーカーはキャッシュに保存されたリソースをすぐに返します。
- デメリット: Service Worker では、HTTP キャッシュをオーバーライドして「ネットワーク優先」リクエストを行うために、追加のキャッシュ破棄が必要です。
まとめ
キャッシュ シナリオの組み合わせは複雑であるため、すべてのケースを網羅する 1 つのルールを設計することはできません。ただし、前のセクションの結果に基づいて、キャッシュ戦略を設計する際に考慮すべきいくつかの推奨事項があります。
- サービス ワーカーのキャッシュ保存ロジックは、HTTP キャッシュ保存の有効期限ロジックと一致している必要はありません。可能であれば、Service Worker で有効期限を長くするロジックを使用して、Service Worker をより細かく制御できるようにします。
- HTTP キャッシュは引き続き重要な役割を果たしますが、ネットワークが不安定な場合や停止している場合は信頼できません。
- 各リソースのキャッシュ戦略を見直し、サービス ワーカーのキャッシュ戦略が HTTP キャッシュと競合することなく価値を提供していることを確認します。