Gatsby のサイト用に Cloudflare のキャッシュを設定してみる

Gatsby で作っている本ブログを、Netlify から Cloudflare Pages に移行した。

Cloudflare Pages のコンテンツが CDN を介して配信されるので、何もしなくても速い。 しかし Cf-Cache-Status ヘッダーが DYNAMIC となっており、CDN からオリジンに問い合わせるような挙動になっているので、ファイルをキャッシュしてパフォーマンスを改善できるか試してみた。

キャッシュしても良い Gatsby のファイルを確認する

Gatsby の推奨ルールが公開されている。

ファイル名にハッシュが付いているものはキャッシュできる (内容が変わるたびにハッシュが変わるため) が、ハッシュが無いものはキャッシュできない。 まとめると以下になる。

  • キャッシュできる
    • static ディレクトリ以下のファイル
    • JavaScript
      • Service Worker 用の /sw.js は除外 (このブログは未使用)
    • CSS
  • キャッシュできない
    • HTML
    • Page data (JSON)
    • App data (JSON)

Cloudflare Pages で Cache-Control ヘッダーを設定するには?

Cloudflare Pages のレスポンスにヘッダーを設定するには、_headers ファイルをルートディレクトリに作成する。

キャッシュしたいファイルのレスポンスに Cache-Control: public, max-age=31536000, immutable ヘッダーを設定する例:

/static/*
  Cache-Control: public, max-age=31536000, immutable
/*.js
  Cache-Control: public, max-age=31536000, immutable
/*.css
  Cache-Control: public, max-age=31536000, immutable

Gatsby のビルド時に _headers ファイルを作成する

Gatsby でビルドした後の public ディレクトリに _headers ファイルを作成する必要がある。本来はシェルスクリプトでファイルをコピーするなどの工夫が必要。

そこで gatsby-plugin-cloudflare-page という Gatsby のプラグインを使う。このプラグインはビルド後のファイルを元に、_headers ファイルを生成してくれる。

生成するファイルの例 (抜粋):

## Created with gatsby-plugin-cloudflare-pages

/*
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff
  Referrer-Policy: same-origin
/styles.bc818bd1644a32038447.css
  Cache-Control: public, max-age=31536000, immutable
/app-bd0deda1f352c15b6ad4.js
  Cache-Control: public, max-age=31536000, immutable
/static/*
  Cache-Control: public, max-age=31536000, immutable
/sw.js
  Cache-Control: no-cache

ちゃんと Gatsby が推奨しているように /sw.js が除外されている。

キャッシュした結果

Developer Tools の Network タブで JavaScript ファイルを確認し、Cache-Control: public, max-age=31536000, immutable ヘッダーが付いていることと、Cloudflare にキャッシュされているかを示す Cf-Cache-Status ヘッダーが HIT (キャッシュ前は MISS) になっていることを確認。

キャッシュ前のレスポンスタイム

キャッシュ後のレスポンスタイム

ファイルサイズが大きなアセットに効果がありそう。

レスポンスタイムが短縮できていることを確認できたが、体感的にはほとんど変わらないので、必ずしも設定する必要はないと考えられる。

© 2025 暇人じゃない. All rights reserved.