AWS Amplifyで動かすNext.jsの限界
はじめに
この記事はディップ Advent Calendar 2024の12日目の投稿です。
2023年にディップへ新卒入社しました、@ryotaneko827 と申します。
総合求人情報サイト「はたらこねっと」のフロントエンド開発を中心に行っており、
2024年5月からは新規メディア「はたらこマガジン」の開発も兼任しています。
背景
Next.jsで開発したアプリケーションをAmplifyにデプロイした際に、
いくつかの制約と不具合に直面したので、その内容を共有します。
これからNext.jsで開発を行う方や、Amplifyを検討している方にとって参考になれば幸いです。
この記事のターゲット
- Next.js (App Router)で開発を行っている方
- AWS上にデプロイを検討している方
はたらこマガジンの技術スタック
はたらこマガジンは、以下の技術スタックで開発を行っています。
フロントエンド
- Next.js v14 (App Router)
- Node.js v22
バックエンド
- microCMS
インフラ
- AWS Amplify Hosting
限界1: SSRモードデプロイする際のビルドサイズに制限がある
Next.jsは通常、SSRアプリケーションとして動作します。
しかし、AmplifyがSSRアプリでサポートしているビルドの最大出力サイズは220MBです。
この制限を超えると、ビルドが失敗してしまいます。
generateStaticParams
などを利用して、ビルド時に静的生成させたい場面があるかも
しれませんが、220MBを超えないように注意が必要です。
実際に発生した問題
generateStaticParams
を利用したらビルドサイズが大きくなった
ビルド時にmicroCMSからデータを取得し、全ての記事を静的生成するように設定しました。
しかし、記事数が増えるにつれてビルドサイズが大きくなり、リリース前の時点で既に220MBを超えてしまいました。
検索ページや、記事のプレビューページではSSRを利用したいため、SSGアプリには移行できませんでした。
限界2: App Routerのキャッシュが正しく機能しない
Next.jsには、オンデマンドでキャッシュを再検証できる機能があります。
しかし、Amplify Hostingではこの機能が正しく機能しません。
実際に発生した問題
revalidatePath
が効かない
Route Handlerを利用して、revalidatePath('/', 'layout')
を実行できるエンドポイントを作成しました。
しかし、エンドポイントを叩くとキャッシュが消去されるのですが、数分後に再度キャッシュが復活してしまう現象が発生しました。
対処法
キャッシュを無効化する
Next.js v14のApp Routerで開発したアプリケーションをAmplifyにデプロイする際は、
layout.tsxに以下のコードを追加して、キャッシュを無効化することをおすすめします。
export const fetchCache = 'force-no-store'
export const dynamic = 'force-dynamic'
SSGアプリとしてデプロイする
ビルド時に全てのデータを取得できる場合は、Static Exportsを利用して、SSGアプリとしてデプロイすることも検討してみてください。
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
...
}
以下の記事が参考になります。
はたらこマガジンにおける今後の課題
現在はキャッシュを無効化する方法を採用しているため、ページの表示速度が遅くなってしまっています。
改善策として、以下の方法を検討しています。
- 脱Amplify Hosting
- ECSもしくはS3 + CloudFrontで運用する
- SSGアプリとしてAmplify Hostingにデプロイする
- ビルド時に静的生成できないページは、API GatewayもしくはCSRで対応する
まとめ
Amplify Hostingは、インフラ環境の構築やデプロイの簡便さが魅力ですが、
実運用レベルでNext.jsを利用する際には、いくつかの制約があることを理解しておく必要があります。
ビルドの最大出力サイズは、もう少し大きくしてほしいです...。
Discussion