概要
- 今後cloudflareで、無料枠でnext.jsを使ってみようと思ってる人向けです
- 従来は pages に next-on-pages を使ってデプロイするのが無料枠で済ませる鉄板でしたが、、、
まず大前提で、今後は cloudflare pagesを使わず、workersにnext.jsをデプロイすべき
タイトルのとおりで
next-on-pagesを使ってcloudflare pages + functinosで動かすのが去年以前の主流でしたが、
ハマりどころ多いし、時間食われるしnext.jsの最新版対応できないし、やめたほうがいいです
すでに公式docでも注記がついており、workersが推奨されています
https://developers.cloudflare.com/pages/framework-guides/nextjs/ssr/
workersは2024年11月から無料で3MBまでデプロイできるようになったし、
1日10万リクエストは無料でいけますし、opennextはいい感じに無料枠を最大限活用できるようにしてくれてます
workers で opennext/cloudflareを使ってnext.jsをホスティングする
opennextはnextをどこでもデプロイできるようにするプロジェクト
cloudflareではworkersに焦点をあてて作られているので、今後はpagesではなくworkersに、opennextを使ってデプロイする、ということになります
Next.jsをpagesで動かすためのアダプタ、next-on-pagesはNext.js 14まで対応ということで
今後は問答無用でこちらを使った方が良いでしょう
workersでnext.js運用した際、静的アセット、画像などは勝手にKVやR2を使ってくれるのでworkersのリクエストを消費しない
next.jsのデフォルトで作られるindexを開くと
xxx.workers.dev/vercel.svg
というvercelのアイコンが表示されます
そのた、トップページリクエスト+画像などのアセットリクエスト分も含めて
workersのリクエストバジェットを消費するのかなと思ってたんですが
cloudflareのメトリクスを見ると、全体を強制リロードしてもリクエスト+1にしかなっていませんでした
これは嬉しい誤算でした
claude3.7sonnetに聞いたら、どうもOpenNextがその辺うまいことKVやR2やらを使ってworkersの消費を抑えてくれているらしい💰️
知識が古い可能性あるので、気になる方は自分で見てみてください
# Cloudflare WorkersとOpenNextの静的アセット配信について
ご質問の内容は、完全に正しい観察です。OpenNextで構築されたNext.jsアプリケーションをCloudflare Workersにデプロイした場合、静的アセット(vercel.svgなどの画像)はワーカーのリクエスト数にカウントされません。
## 仕組みの解説
1. **アセット配信の最適化**:
- OpenNextは、静的アセット(画像、CSS、JS、フォントなど)をCloudflare R2またはWorkers KVに保存します
- これらのアセットは、Workers KVまたはR2から直接CDN経由で配信されます
- したがって、Workersのリクエスト数としてカウントされません
2. **具体的な動作**:
- ユーザーがページ(`https://imgboard.parupunte.workers.dev/`)にアクセスすると、Workersがリクエストを処理します(+1カウント)
- 同じページ内の画像(`/vercel.svg`)は、Workers KVから直接配信され、Workersリクエストは発生しません
- これは意図的な最適化設計で、Workersの無料枠(1日10万リクエスト)を効率的に使用するためです
3. **package.jsonの設定**:
- `@opennextjs/cloudflare`のバージョン`1.0.0-beta.3`を使用しており、この機能が組み込まれています
- デプロイ時に`opennextjs-cloudflare build && opennextjs-cloudflare deploy`コマンドが実行され、最適な配信設定が適用されます
## 利点
この仕組みには大きな利点があります:
1. **コスト効率**:
- 静的アセットがWorkersリクエストを消費しないため、無料枠を主に動的コンテンツに使用できます
2. **パフォーマンス**:
- 静的アセットがCDNから直接配信されるため、読み込み速度が向上します
3. **スケーラビリティ**:
- 画像などの大量のアセットがあっても、Workersのリクエスト制限に影響しません
そのため、観察されている動作は正常で、むしろOpenNextの優れた最適化の一例です。
pages + next-on-pagesの場合、 AppRoute 動的ルーティングがNext.js 15だと動かない
以下エラーで、問答無用でstatus code500になる
"Error: Disallowed operation called within global scope. Asynchronous I/O (ex: fetch() or connect()), setting a timeout, and generating random values are not allowed within global scope. To fix this error, perform this operation within a handler. https://developers.cloudflare.com/workers/runtime-apis/handlers/"
こういう問題もあり、next-on-pagesはもう使わないほうがいいですね