Site cover image
Next.js+Google Cloud CDNで静的ファイルをキャッシュする

Next.js アプリケーションを Vercel でホストする場合、私たち開発者が何も考えなくても Vercel が JS ファイルや画像ファイルなどの静的ファイルを良い感じにキャッシュしてくれます。

一方、Vercel 以外でホストする場合には、当然ながらキャッシュ周りを自分で設定する必要があります。

このエントリでは、Next.js を Google Cloud にホストしたケースを想定して静的ファイルをキャッシュする方法を紹介します。

💁‍♂️
より安価に CDN を構築するには Cloud RunのカスタムドメインマッピングでCloudflareを使う をご覧ください

Cloud CDN では下記の条件を満たしているときコンテンツをキャッシュします。Next.js を普通に使っている限りは問題ないと思います。

また、Cloud CDN はキャッシュ制御ディレクティブに沿ってコンテンツをキャッシュします。

max-age ディレクティブがある場合はその指定秒間 CDN にキャッシュします。

s-maxage ディレクティブがある場合は max-age ディレクティブよりも優先されます。

また、 stale-while-revalidate も利用可能です。

Next.js のビルドで生成される静的ファイルは _next/static ディレクトリ以下に配置されます。

これらのファイルをレスポンスする場合は Next.js がヘッダに自動的に cache-control: public,max-age=7200,immutable を付けてくれます。ついでに言うと etag も付きます。

ですので _next/static のファイルは特に考慮しなくても CDN にキャッシュされます。

public ディレクトリ以下の静的ファイルは、レスポンスヘッダに cache-control: public,max-age=0 のように max-age=0 が付くため実質的に CDN にはキャッシュされず、毎回オリジンサーバーにリクエストが行きます。

これを防ぐには、 next.config.jsheaders ディレクティブでレスポンスヘッダを明示的に指定する必要があります。

例えば、 public ディレクトリにある favicon.ico ファイルと images/ ディレクトリ以下の全てのファイルをキャッシュする場合は下記のようにします。

module.exports = {
  headers() {
    return [
      {
        source: '/favicon.ico',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=2592000, stale-while-revalidate=86400',
          },
        ],
      },
      {
        source: '/images/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=2592000, stale-while-revalidate=86400',
          },
        ],
      },
    ]
  },
}

参考

public ディレクトリ以下のファイルがデフォルトで max-age=0 を返してしまう件については、catnose さんも Next.jsのpublicディレクトリ内のファイルのキャッシュの挙動 で同様に書かれています。

以上です。このエントリでは Next.js を Google Cloud にホストしたケースを想定して静的ファイルをキャッシュする方法を紹介しました。

Thank you!
Thank you!
URLをコピーしました

コメントを送る

コメントはブログオーナーのみ閲覧できます