Next.js アプリケーションを Vercel でホストする場合、私たち開発者が何も考えなくても Vercel が JS ファイルや画像ファイルなどの静的ファイルを良い感じにキャッシュしてくれます。
一方、Vercel 以外でホストする場合には、当然ながらキャッシュ周りを自分で設定する必要があります。
このエントリでは、Next.js を Google Cloud にホストしたケースを想定して静的ファイルをキャッシュする方法を紹介します。
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.js
の headers
ディレクティブでレスポンスヘッダを明示的に指定する必要があります。
例えば、 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 にホストしたケースを想定して静的ファイルをキャッシュする方法を紹介しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます