Service Worker キャッシュと HTTP キャッシュ

サービス ワーカー キャッシュ レイヤと HTTP キャッシュ レイヤで、一貫した有効期限ロジックを使用するか、異なる有効期限ロジックを使用するかについてのメリットとデメリット。

サービス ワーカーと PWA が最新のウェブ アプリケーションの標準になりつつある一方で、リソース キャッシュはかつてないほど複雑になっています。この記事では、ブラウザのキャッシュの概要について説明します。

  • サービス ワーカーのキャッシュと HTTP キャッシュのユースケースと違い。
  • 通常の HTTP キャッシュ戦略と比較した、さまざまなサービス ワーカーのキャッシュ有効期限戦略の長所と短所。

キャッシュ フローの概要

大まかに言うと、ブラウザはリソースをリクエストするときに、次のキャッシュ順序に従います。

  1. Service Worker キャッシュ: Service Worker は、リソースがキャッシュ内にあるかどうかを確認し、プログラムされたキャッシュ戦略に基づいてリソース自体を返すかどうかを決定します。なお、この処理は自動的には行われません。Service Worker で取得イベント ハンドラを作成し、ネットワーク リクエストをインターセプトして、リクエストがネットワークではなく Service Worker のキャッシュから提供されるようにする必要があります。
  2. HTTP キャッシュ(ブラウザ キャッシュ): リソースが HTTP キャッシュにあり、有効期限が切れていない場合、ブラウザは HTTP キャッシュ内のリソースを自動的に使用します。
  3. サーバーサイド: Service Worker キャッシュまたは HTTP キャッシュに何も見つからない場合、ブラウザはネットワークにアクセスしてリソースをリクエストします。リソースが CDN にキャッシュされていない場合、リクエストは送信元サーバーにまで戻る必要があります。

キャッシュのフロー

キャッシュ レイヤ

Service Worker のキャッシュ

Service Worker は、ネットワーク タイプの HTTP リクエストをインターセプトし、キャッシュ戦略を使用して、ブラウザに返すリソースを決定します。Service Worker キャッシュと HTTP キャッシュは同じ一般的な目的を果たしますが、Service Worker キャッシュは、キャッシュに保存する内容とキャッシュの保存方法をきめ細かく制御できるなど、より多くのキャッシュ機能が提供されます。

Service Worker キャッシュの制御

サービス ワーカーは、イベント リスナー(通常は fetch イベント)を使用して HTTP リクエストをインターセプトします。次のコード スニペットは、キャッシュファースト キャッシュ戦略のロジックを示しています。

サービス ワーカーが HTTP リクエストをインターセプトする方法を示した図

自転車の再発明を避けるため、Workbox を使用することを強くおすすめします。たとえば、1 行の正規表現コードでリソース URL パスを登録できます。

import {registerRoute} from 'workbox-routing';

registerRoute(new RegExp('styles/.*\\.css'), callbackHandler);

サービス ワーカーのキャッシュ戦略とユースケース

次の表に、一般的なサービス ワーカーのキャッシュ戦略と、各戦略が役立つ場合を示します。

対策 更新頻度の根拠 ユースケース
ネットワークのみ コンテンツは常に最新の状態にする必要があります。
  • お支払いと購入手続き
  • 残高明細書
ネットワークから取得できなければキャッシュから取得 新しいコンテンツを配信することをおすすめします。ただし、ネットワークに障害が発生した場合やネットワークが不安定な場合は、少し古いコンテンツを配信してもかまいません。
  • タイムリーなデータ
  • 料金(免責条項が必要)
  • 注文ステータス
Stale-while-revalidate キャッシュに保存されたコンテンツをすぐに配信してもかまいませんが、今後は更新されたキャッシュに保存されたコンテンツを使用する必要があります。
  • ニュース フィード
  • 商品リスティング ページ
  • メッセージ
キャッシュに保存してからネットワークにフォールバックする コンテンツは重要ではなく、パフォーマンスを向上させるためにキャッシュから提供できますが、サービス ワーカーは定期的に更新を確認する必要があります。
  • アプリシェル
  • 共通リソース
キャッシュのみ コンテンツが変更される可能性はほとんどありません。
  • 静的コンテンツ

Service Worker のキャッシュ保存のその他のメリット

サービス ワーカーのキャッシュ保存では、キャッシュ保存ロジックのきめ細かい制御に加えて、次のようなメリットがあります。

  • オリジンのメモリとストレージ容量の増加: ブラウザは、HTTP キャッシュ リソースをオリジンごとに割り当てます。つまり、複数のサブドメインがある場合、それらはすべて同じ HTTP キャッシュを共有します。オリジン/ドメインのコンテンツが HTTP キャッシュに長時間保持されるとは限りません。たとえば、ユーザーがブラウザの設定 UI から手動でクリーンアップするか、ページでハードリロードをトリガーすることで、キャッシュをパージする場合があります。サービス ワーカー キャッシュを使用すると、キャッシュに保存されたコンテンツがキャッシュに残る可能性が大幅に高まります。詳細については、永続ストレージをご覧ください。
  • 不安定なネットワークやオフライン エクスペリエンスでの柔軟性の向上: HTTP キャッシュでは、リソースをキャッシュに保存するかしないかの 2 つの選択肢しかありません。サービス ワーカーのキャッシュを使用すると、小さな「ハプニング」を簡単に軽減できます(「再検証中の古いコンテンツ」戦略を使用)。また、完全なオフライン エクスペリエンスを提供することもできます(「キャッシュのみ」戦略を使用)。さらに、ページの一部をサービス ワーカー キャッシュから取得し、一部を除外するカスタマイズされた UI など、中間的なエクスペリエンスも提供できます(「キャッチ ハンドラを設定する」戦略を使用)。

HTTP キャッシュ

ブラウザがウェブページと関連リソースを初めて読み込むと、これらのリソースは HTTP キャッシュに保存されます。通常、HTTP キャッシュは、エンドユーザーが明示的に無効にしていない限り、ブラウザによって自動的に有効になります。

HTTP キャッシュを使用するということは、リソースをキャッシュするタイミングとキャッシュ保存時間をサーバーに依存することを意味します。

HTTP レスポンス ヘッダーで HTTP キャッシュの有効期限を制御する

サーバーがリソースのブラウザ リクエストに応答すると、サーバーは HTTP レスポンス ヘッダーを使用して、リソースをキャッシュに保存する期間をブラウザに伝えます。詳細については、レスポンス ヘッダー: ウェブサーバーを構成するをご覧ください。

HTTP キャッシュ戦略とユースケース

HTTP キャッシュは、時間ベース(TTL)のリソースの有効期限ロジックのみを処理するため、Service Worker のキャッシュよりもはるかにシンプルです。HTTP キャッシュ戦略の詳細については、使用するレスポンス ヘッダーの値概要をご覧ください。

キャッシュの有効期限ロジックの設計

このセクションでは、サービス ワーカー キャッシュ レイヤと 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 キャッシュの価値は低くなります。

シナリオ: 中期キャッシュ保存(Stale-while-revalidate)

  • キャッシュに保存されたリソースが有効な場合(1 日以下): Service Worker はキャッシュに保存されたリソースをすぐに返します。その後、ネットワークにアクセスしてリソースを取得します。ブラウザの HTTP キャッシュにリソースのコピーがあるため、そのコピーをサービス ワーカーに返します。
  • キャッシュに保存されたリソースが期限切れの場合(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 キャッシュ保存の有効期限ロジックと一致している必要はありません。可能であれば、サービス ワーカーで有効期限の長いロジックを使用して、サービス ワーカーにより多くの制御権を付与します。
  • HTTP キャッシュは引き続き重要な役割を果たしますが、ネットワークが不安定な場合や停止している場合は信頼できません。
  • 各リソースのキャッシュ戦略を見直し、サービス ワーカーのキャッシュ戦略が HTTP キャッシュと競合することなく価値を提供していることを確認します。

その他の情報