Cloud CDN は、App Hosting によるウェブアプリのサポートの重要な部分です。バックエンドへのすべてのリクエストは、まず Cloud CDN を経由します。CDN にすでにキャッシュに保存されているコンテンツは、ウェブアプリのサーバーコードを実行している Cloud Run サービスへのアクセスをスキップして、ユーザーにすぐに提供されます。CDN の一般的なメリットについては、web.dev をご覧ください。
基本的な Cloud CDN 構成は App Hosting によって設定され、変更できませんが、キャッシュを最適化してページの読み込み速度を向上させ、キャッシュに保存されていないコンテンツの課金を減らし、Cloud Run へのトラフィックを最小限に抑えるために、さまざまな方法があります。
キャッシュに保存可能なコンテンツ
次の条件がすべて true の場合、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
ヘッダーがあるレスポンスの
Vary
ヘッダーに、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
以外の値が設定されている。レスポンスには、
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 では、明示的な cache-control ディレクティブは設定されていません。独自のヘッダーを追加するには、サーバー ルートでキャッシュ制御ヘッダーを指定します。たとえば、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 で変換は適用されません。 |
キャッシュに保存されたトラフィックとキャッシュに保存されていないトラフィックを測定する
App Hosting コンソールの [使用状況] タブの [Cloud CDN - アウトバウンド 帯域幅] グラフには、キャッシュに保存されたバイトとキャッシュに保存されていないバイト数が表示され、ロールアウトごとにマークが付けられます。このグラフを使用して、キャッシュの最適化の効果を測定できます。