Cloud CDN は、App Hosting がウェブアプリをサポートするうえで重要な役割を果たします。バックエンドへの リクエストはすべて、まず Cloud CDN を通過します。CDN にすでにキャッシュされているコンテンツは、ウェブアプリのサーバーコードを実行している Cloud Run サービスへのアクセスをスキップして、ユーザーにすぐに配信されます。CDN の一般的なメリットについて詳しくは、 web.dev をご覧ください。
基本的な Cloud CDN 構成は App Hosting によって設定され、変更することはできませんが、キャッシュを最適化してページ読み込み速度を向上させ、キャッシュされていないコンテンツの課金を減らし、Cloud Run へのトラフィックを最小限に抑えるために、さまざまな方法があります。
キャッシュに保存可能なコンテンツ
次の条件をすべて 満たす場合、Cloud CDN はレスポンスをキャッシュに保存します。
リクエストが GET である
レスポンスのステータス コードが
200、203、204、206、300、301、302、307、308、404、405、410、421、451、501のいずれかである。レスポンスに、
max-ageまたはs-maxageディレクティブを含むCache-Controlヘッダー、あるいは将来のタイムスタンプを含むExpiresヘッダーがある。レスポンスに
Ageヘッダー、または明示的なpublicディレクティブを含むCache-Controlヘッダーがある。レスポンスのサイズが 10 MiB 以下である。
次の条件をいずれも 満たさない場合:
レスポンスに
Set-Cookieヘッダーがあるレスポンスに、
Accept、Accept-Encoding、Access-Control-Request-Headers、Access-Control-Request-Method、Origin、Sec-Fetch-Dest、Sec-Fetch-Mode、Sec-Fetch-Site、X-Goog-Allowed-Resources、X-Origin、RSC、Next-Router-State-Tree、Next-Router-Prefetch、またはNext-Router-Segment-Prefetch以外の値を含むVaryヘッダーがある。レスポンスに、
no-storeまたはprivateディレクティブを含むCache-Controlヘッダーがある。リクエストに、
no-storeディレクティブを含むCache-Controlヘッダーがある。レスポンスに明示的なキャッシュ制御ディレクティブがない限り、リクエストに
Authorizationヘッダーがある。
キャッシュ制御ディレクティブを使用して動作をカスタマイズする
Next.js
Next.js は、さまざまな要因に基づいてキャッシュ制御ディレクティブを暗黙的に設定します。ただし、
手動でヘッダーを設定することで、これらをオーバーライドできます。
next.config.jsファイル。たとえば、ページが Cloud CDN にキャッシュされないようにするには、次のようにします。
/** @type {import('next').NextConfig} */
const nextConfig = {
headers: async () => [{
source: "/YOUR_PRIVATE_PAGE",
headers: [{
key: "Cache-Control",
value: "private"
}],
}],
};
Angular
Angular SSR は、デフォルトで明示的なキャッシュ制御ディレクティブを設定しません。サーバー ルートでキャッシュ制御ヘッダーを指定することで、独自のヘッダーを追加できます。たとえば、Cloud CDN がすべてのページを 1 時間キャッシュできるようにするには、次のようにします。
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
{
path: '**',
renderMode: RenderMode.Prerender,
headers: {
'Cache-Control': 'public, max-age=3600',
}
}
];
または、特定のページがキャッシュされないようにするには、次のようにします。
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
// ... other routes
{
path: 'YOUR_PRIVATE_PAGE',
renderMode: RenderMode.Server,
headers: {
'Cache-Control': 'private',
}
}
];
重視されるディレクティブ
Firebase App Hosting の Cloud CDN インスタンスは、次のキャッシュ制御 ディレクティブを尊重します。
| ディレクティブ | リクエスト | レスポンス |
|---|---|---|
no-store |
リクエストに含まれている場合、レスポンスはキャッシュに保存されません。 | no-store を含むレスポンスはキャッシュに保存されません。 |
no-cache |
no-cache リクエスト ディレクティブは無視され、クライアントが送信元に対する再検証を開始または強制する可能性が回避されます。 |
no-cache を含むレスポンスはキャッシュに保存されますが、配信前に送信元で再検証する必要があります。 |
public |
なし | このディレクティブはキャッシュへの保存に必須ではありませんが、プロキシによってキャッシュに保存されるコンテンツには、このディレクティブを含めることが効果的な手法です。 |
private |
なし | private ディレクティブを含むレスポンスは、レスポンスがその他の理由でキャッシュ保存可能であるとみなされる場合でも、Cloud CDN によってキャッシュに保存されません。クライアント(ブラウザなど)は、引き続き結果をキャッシュに保存する可能性があります。レスポンスのキャッシュへの保存をすべて回避するには、no-store を使用します。 |
max-age=SECONDS |
max-age リクエスト ディレクティブは無視されます。キャッシュに保存されたレスポンスは、このヘッダーがリクエストに含まれていない場合と同様に返されます。 |
max-age ディレクティブを含むレスポンスは、最大で SECONDS までキャッシュに保存されます。 |
s-maxage=SECONDS |
なし | s-maxage ディレクティブを含むレスポンスは、最大で SECONDS までキャッシュに保存されます。max-age と s-maxage の両方が存在する場合、s‑maxage が Cloud CDN で使用されます。このディレクティブを含む古くなったレスポンスは配信されません。s-max-age(2 つのハイフン)は、キャッシュを保存する目的に対しては無効です。 |
max-stale=SECONDS |
max-stale リクエスト ディレクティブは、クライアントが受け入れ可能な最大ステイルネス(秒単位)を指定します。 Cloud CDN はこれを適用し、レスポンスのステイルネスが max-stale ディレクティブより小さい場合にのみ、古いキャッシュ レスポンスを返します。それ以外の場合は、リクエストのサービスを提供する前に再検証します。 |
なし |
stale-while-revalidate=SECONDS |
なし | 再検証が非同期で行われている間、stale-while-revalidate を含むレスポンスは最大で SECONDS の間クライアントに配信されます。 |
must-revalidate |
なし | must-revalidate を含むレスポンスは、有効期限が経過した後に配信元サーバーで再検証されます。このディレクティブを含む古くなったレスポンスは配信されません。 |
proxy-revalidate |
proxy-revalidate を含むレスポンスは、有効期限が経過した後に配信元サーバーで再検証されます。このディレクティブを含む古くなったレスポンスは配信されません。 |
|
no-transform |
なし | Cloud CDN で変換は適用されません。 |
キャッシュされたトラフィックとキャッシュされていないトラフィックを測定する
Firebase コンソールの [App Hosting] > [Usage] タブの [Cloud CDN - 送信帯域幅] グラフには、キャッシュされたバイト数とキャッシュされていないバイト数が表示され、 ロールアウトごとにマークが付いています。このグラフを使用して、キャッシュの最適化の効果を測定できます。
ルートベースのモニタリングを使用して、ウェブアプリの特定のルートのキャッシュ ヒット率を確認することもできます。