キャッシュ動作を管理する

Firebase Hosting は、強力なグローバル CDN を使用してサイトを高速化します。

リクエストされた静的コンテンツは CDN で自動的にキャッシュに保存されます。サイトのコンテンツを再デプロイすると、キャッシュに保存されたコンテンツは CDN 全体から自動的にクリアされ、次のリクエストまでそのままになります。

ただし、Cloud Functions サービスと Cloud Run サービスはコンテンツを動的に生成するため、特定の URL に対応するコンテンツは、ユーザーが入力した情報やユーザー ID などに応じて変わります。これを考慮するため、バックエンド コードによって処理されるリクエストは、デフォルトでは CDN でキャッシュに保存されません

ただし、動的コンテンツのキャッシュの動作はユーザーが構成できます。たとえば、ある関数が新しいコンテンツを定期的に生成する場合は、生成されたコンテンツを少なくとも短期間キャッシュに保存することでアプリを高速化できます。

同様にキャッシュの動作を構成して、そのコンテンツはトリガーされた関数からではなく CDN から配信されるため、関数の実行コストを削減できる可能性があります。関数の実行やサービスの最適化の詳細については、Cloud FunctionsCloud Run のドキュメントをご覧ください。

404 エラーを返すリクエストは例外となります。CDN は、存在しない URL に対するサービスの 404 レスポンスを 10 分間キャッシュに保存します。これにより、その URL に対する後続のリクエストは CDN から提供されます。コンテンツがこの URL に存在するようにサービスを変更すると、CDN はキャッシュされた 404 を(最大で)10 分間配信し続け、その後、通常どおりその URL からコンテンツを配信します。

404 レスポンスに Cloud Functions または Cloud Run サービスによって設定されたキャッシュ ヘッダーがすでに含まれている場合、デフォルトの 10 分がオーバーライドされ、CDN のキャッシュ動作が完全に決定されます。

キャッシュの動作の詳細については、Google のウェブ デベロッパー向けドキュメントをご覧ください。

Cache-Control を設定する

動的コンテンツのキャッシュ管理に使用する主なツールは、Cache-Control ヘッダーです。このヘッダーを設定することで、コンテンツのキャッシュ可能期間をブラウザと CDN の両方に伝えることができます。関数内で、Cache-Control を次のように設定します。

res.set('Cache-Control', 'public, max-age=300, s-maxage=600');

このサンプル ヘッダーの各ディレクティブは、次の 3 つのことを行います。

  • public - キャッシュを public としてマークします。つまり、ブラウザと中間サーバー(Firebase Hosting では CDN を意味します)の両方がコンテンツをキャッシュに保存できます。

  • max-age - コンテンツをキャッシュに保存できる秒数をブラウザと CDN に伝えます。設定された時間が経過すると、ブラウザと CDN はオリジン サーバーでコンテンツを再検証する必要があります。上記のサンプル ヘッダーでは、ブラウザと CDN がコンテンツを 5 分間キャッシュに保存できるようしています(CDN キャッシュのみの制御については、下記の s-maxage をご覧ください)。

  • s-maxage - CDN キャッシュの動作のみについて max-age ディレクティブをオーバーライドします。この値は CDN でコンテンツをキャッシュに保存できる秒数を指定します。設定された時間が経過すると、CDN はオリジン サーバーでコンテンツを再検証する必要があります。上記のサンプル ヘッダーでは、CDN のみについて max-age の設定をオーバーライドし、CDN がコンテンツを 10 分間キャッシュに保存できるようにしています。

max-ages-maxage の値は、ユーザーが古くなったコンテンツを受け取っても問題ないと考えられる最も長い時間に設定します。数秒ごとにページが変わる場合は、短い時間に設定してください。コンテンツのタイプによっては、数時間、数日、または数か月キャッシュに保存しても支障がないことがあります。

Cache-Control ヘッダーの詳細については、Mozilla Developer Network のドキュメントおよび Google のウェブ デベロッパー向けドキュメントをご覧ください。

キャッシュに保存されたコンテンツが配信されるタイミング

ブラウザと CDN は、以下に基づいてコンテンツをキャッシュに保存します。

  • ホスト名
  • パス
  • クエリ文字列
  • Vary ヘッダーで指定されたリクエスト ヘッダーの内容

Vary ヘッダー

Vary ヘッダーは、適切なレスポンス(キャッシュに保存されたコンテンツが有効か、またはコンテンツをオリジン サーバーで再検証する必要があるか)を提供するためにどのリクエスト ヘッダーを使用すればよいかを決定します。

Firebase Hosting では、一般的な状況のレスポンスについては適切な Vary ヘッダーが自動的に設定されます。ほとんどの場合、Vary ヘッダーについて気にする必要はありません。ただし、高度なユースケースでは、キャッシュを制御するために他のヘッダーが必要になる場合もあります。その場合は、次の例のようにレスポンスに Vary ヘッダーを設定できます。

res.set('Vary', 'Accept-Encoding, X-My-Custom-Header');

この場合、Vary ヘッダーの値は次のようになります。

vary: X-My-Custom-Header, x-fh-requested-host, accept-encoding, cookie, authorization

これらの設定を使用すると、X-My-Custom-Header ヘッダーが異なる以外は同一である 2 つのリクエストが別々にキャッシュされます。動的コンテンツに対してリクエストが行われると、Hosting はデフォルトで CookieAuthorizationVary ヘッダーを追加します。これにより、使用されるセッションまたは Cookie 認証ヘッダーはどれもキャッシュキーの一部になっていることが保証されるため、コンテンツが誤って漏洩することを防げます。

また、次の点にも注意してください。

  • キャッシュに保存できるのは GET リクエストと HEAD リクエストだけです。他のメソッドを使用した HTTPS リクエストはキャッシュに保存されません。

  • Vary ヘッダーに設定を追加する際は注意が必要です。追加する設定が多いほど、キャッシュに保存されたコンテンツを CDN から配信できる可能性は低くなります。また、Varyレスポンス ヘッダーではなく、リクエスト ヘッダーに基づいて処理を決定します。

Cookie の使用

Firebase Hosting と Cloud Functions または Cloud Run を併用すると、通常は受信リクエストから Cookie が削除されます。この処理は、CDN キャッシュの動作を効率化するために必要になります。__session という特別な名前の Cookie だけがアプリに到達できます。

__session Cookie が存在する場合、その Cookie はキャッシュキーの一部に自動的に組み込まれます。そのため、異なる Cookie を持つ 2 人のユーザーが、キャッシュに保存された相手のレスポンスを受信することはできません。__session Cookie は、ユーザー承認に応じてアプリから異なるコンテンツが配信される場合にのみ使用してください。