ヘッドレスCMSを使ってブログを構築したときに「AWSでやってほしい」というクライアント要望がありました。
調べると AWS Amplify Hosting が Next.jsのISR(Incremental Static Regeneration)に対応していると書いてある。
「これで行けそうじゃん」と思って進めたのですが……結果的には結構ハマりました。
困りポイント1: オンデマンドISRに非対応
ブログという性質上、オンデマンドISR(revalidate API) があると便利です。
- コスト面 → 更新した記事だけ再生成できるので安上がり
- 体験面 → 新しい記事が即反映される
ただし Amplify は オンデマンドISR非対応。
予算やスケジュールの都合で自前カスタマイズは選択肢になく、泣く泣く断念しました。
困りポイント2: リロードする度に記事が出たり消えたりする
これが最大のハマりポイント。
具体的には:
- 公開した記事が リロードするたびに表示されたり消えたりする
- 非公開にした記事も 数分の間チラつく
revalidate: 60 にしていましたが、実際には 5〜10分(300〜600秒)以上の不整合を確認。
時間の都合で完全に原因追及まではしていませんが、構造的にはこう理解しています:
- CloudFront のキャッシュ
- しかも拠点が複数
- Lambda が複数インスタンス立ち上がる
この組み合わせで「どのCDNから取るか/どのLambdaに当たるか」で挙動が揺れている様子でした。
しっかり検証するなら
レスポンスヘッダーの
- age
- x-amz-cf-pop
- x-cache
などを確認しつつ、Lambda側もしっかりログ入れ込みながら検証していく感じになりそうです。
試したこと
CFキャッシュ無効化
→ Next.js の ISR だけに任せれば解決すると思ったけど、Lambda インスタンスガチャ問題でNG。
Next.js 側 ISR 無効化
→ 代わりに CF の stale-while-revalidate を活用。これが一番安定しました。
# 1) その他設定..
# 2) その他設定..
# 3) 静的ファイル以外すべてCloudFront側でSWRを実行
- pattern: "/*"
headers:
- key: Cache-Control
value: "public, max-age=0, s-maxage=60, stale-while-revalidate=300"
結論
- ISRをちゃんと使いたいなら Vercel 一択
- Amplifyで楽したいなら ISRは諦めて SSR+CloudFrontのswrを使う のが現実的
「AmplifyでISR使えるって書いてあるけどそれだけだと本番運用に耐えないよ」というのが今回の学びでした。
同じように「AWSでNext.jsブログやりたい」方の参考になれば幸いです。