Firebase Hosting は、強力なグローバル CDN を使用してサイトを高速化します。
リクエストされた静的コンテンツは CDN で自動的にキャッシュに保存されます。サイトのコンテンツを再デプロイすると、キャッシュに保存された静的コンテンツは CDN 全体から自動的にクリアされ、次のリクエストまでそのままになります。
ただし、Cloud Functions サービスと Cloud Run サービスはコンテンツを動的に生成するため、特定の URL に対応するコンテンツは、ユーザーが入力した情報やユーザー ID などに応じて変わります。これを考慮するため、バックエンド コードによって処理されるリクエストは、404 エラーを返すリクエストを除き、デフォルトでは CDN でキャッシュに保存されません。キャッシュに保存された 404 の結果を削除するには、Firebase Hosting を再デプロイします。Cloud Functions と Cloud Run を再デプロイしても、キャッシュが自動的に無効になることはありません。
ただし、動的コンテンツのキャッシュの動作はユーザーが構成できます。たとえば、ある関数が新しいコンテンツを定期的に生成する場合は、生成されたコンテンツを少なくとも短期間キャッシュに保存することでアプリを高速化できます。
また、そのコンテンツはトリガーされた関数からではなく CDN から配信されるため、場合によっては関数の実行コストも削減できます。関数の実行やサービスの最適化の詳細については、Cloud Functions と Cloud Run のドキュメントをご覧ください。
キャッシュの動作の詳細については、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-age
と s-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 はデフォルトで Cookie
と Authorization
を Vary
ヘッダーを追加します。これにより、使用されるセッションまたは 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 は、ユーザー承認に応じてアプリから異なるコンテンツが配信される場合にのみ使用してください。