【ITニュース解説】Migrating to Next.js 15: big wins, small gotchas
2026年09月18日に「Dev.to」が公開したITニュース「Migrating to Next.js 15: big wins, small gotchas」について初心者にもわかりやすく解説しています。
ITニュース概要
Next.js 15への移行は開発を高速化し、React 19もサポートする。ただし、`cookies()`などのAPIは非同期になり`await`が必須。また、`fetch()`やGETハンドラのキャッシュはデフォルトで無効化されたため、明示的な設定が必要だ。移行時にこれらの変更点に注意し、コードを適切に修正しよう。
ITニュース解説
Next.js 15へのアップグレードは、Webアプリケーション開発において多くの大きな進歩をもたらすが、同時にいくつかの重要な変更点があり、これらを理解しておく必要がある。この新しいバージョンは、開発者の作業効率を劇的に向上させ、アプリケーションのパフォーマンスを最適化するための強力な新機能を導入している。
まず、最も注目すべきメリットの一つは、開発環境での速度向上だ。Next.js 15では、開発サーバーがTurbopackという新しいエンジンを採用しており、これによりアプリケーションの起動時間や、コードを変更した際の更新(ホットモジュールリロード、HMR)が格段に速くなる。具体的な数値として、ビルド速度が4倍から7倍速くなり、HMRの遅延が100ミリ秒以下になるという報告もある。これは開発者にとって、コードを書いてからその結果を確認するまでの待ち時間が大幅に減ることを意味し、作業の中断が少なくなり、集中力を保ちやすくなる。結果として、新しい機能の実験やデバッグがよりスムーズに進むようになる。
また、Next.js 15はReact 19をサポートする。これにより、最新のReactが提供する最適化機能や新しいAPIを利用できるようになり、アプリケーションの効率性や保守性が向上する可能性がある。さらに、「Partial Prerendering(PPR)」という機能も導入された。これは、ウェブページの一部を静的に事前に生成し、ユーザーにすぐに表示できるようにすることで、ページの読み込み速度を向上させる技術だ。そして、動的なコンテンツだけを後からストリーミングで表示できるため、初期の描画が非常に高速になる。これにより、特にLarge Contentful Paint(LCP)のような重要なパフォーマンス指標が改善され、ユーザー体験が向上する。
しかし、これらの素晴らしいメリットを享受するためには、移行時に注意すべき重要な変更点が二つある。これらはアプリケーションの動作に影響を与える可能性があるため、慎重な対応が求められる。
一つ目の変更点は、「リクエストスコープAPI」の動作が非同期になったことだ。リクエストスコープAPIとは、ウェブサーバーがユーザーからのリクエストを受け取った際に、そのリクエスト固有の情報を取得するための機能群を指す。例えば、ウェブサイトのクッキー(cookies())、リクエストヘッダー(headers())、URLパスに含まれるパラメータ(params)、URLのクエリパラメータ(searchParams)などがこれに該当する。Next.js 15より前のバージョンでは、これらのAPIは同期的に、つまりコードが書かれた順にすぐに結果を返していた。しかし、Next.js 15からは、これらのAPIはPromiseを返すようになった。Promiseとは、将来的に値が利用可能になることを示すJavaScriptのオブジェクトで、その値を取得するためにはawaitキーワードを使って待つ必要がある。
もし、以前のコードがこれらのAPIをawaitせずに同期的に使用していた場合、そのままアップグレードすると、開発環境では動くように見えても、本番環境で予期せぬエラーが発生する可能性がある。よくある失敗例としては、認証のためのミドルウェア関数がクッキー情報を同期的に読み取ろうとし、実際にはPromiseが解決される前にその値を使おうとしてエラーになるケースがある。この問題を解決するには、クッキーやヘッダーなどのリクエストスコープAPIを呼び出す際に必ずawaitキーワードを使い、これらのAPIを呼び出す関数自体もasync関数として定義する必要がある。例えば、cookies()を呼び出す際には、const cookieStore = await cookies();のように書き換える必要がある。Next.jsチームは、この移行作業を自動化する「codemod」というツールを提供しているが、複雑なコードパターンでは手動での確認と修正も依然として重要となる。
二つ目の重要な変更点は、fetch()関数とGETリクエストを処理するルートハンドラーのキャッシュ動作のデフォルト設定が変更されたことだ。以前のNext.jsでは、これらの処理が暗黙的にキャッシュされることがあったが、Next.js 15からは、明示的にキャッシュするように指定しない限り、デフォルトでキャッシュされない(no-store相当)ように変更された。これは、意図しない古いデータがユーザーに表示されることを防ぎ、常に最新の情報を取得するための変更と言える。
しかし、この変更によって、以前のバージョンで暗黙的なキャッシュに依存していたアプリケーションは、アップグレード後に予期せぬ問題に直面する可能性がある。具体的には、バックエンドサーバーやAPIへのリクエストが急増し、サーバーに大きな負荷がかかったり、意図せずアプリケーションのパフォーマンスが低下したりすることが考えられる。この問題を解決するには、キャッシュが必要なfetch()呼び出しやGETルートハンドラーに対して、明示的にキャッシュの挙動を設定する必要がある。例えば、静的でめったに変わらないデータを取得するfetch()には、cache: 'force-cache'オプションを追加して強制的にキャッシュさせる。あるいは、特定の期間が過ぎたらキャッシュを再検証する「Incremental Static Regeneration(ISR)」のような動作を実現したい場合は、next: { revalidate: seconds }オプションを設定する。ルートハンドラーの場合も、export const dynamic = 'force-static'やexport const revalidate = 3600のように明示的な設定を行う。このように、開発者はどのデータがどの程度の頻度で更新されるかを考慮し、適切なキャッシュ戦略を明示的に選択する意識が求められる。ユーザー固有のデータにはキャッシュを適用せず、広く共有されるリソースにはキャッシュを適用するなど、目的に応じた使い分けが重要になる。
その他にも、Next.js 15への移行は、Server Componentsの採用をさらに推進する良い機会となる。Server Componentsを積極的に利用することで、クライアントサイドに送られるJavaScriptの量を減らし、アプリケーションのバンドルサイズを小さくできる。これは、特にモバイル環境でのページの読み込み速度向上に直結し、より良いユーザー体験を提供することにつながる。Partial Prerenderingと組み合わせることで、静的なシェルを即座に表示しつつ、動的な部分を効率的にストリーミングできるため、極めて高いパフォーマンスを実現できる。
具体的な移行プロセスとしては、まずNext.jsとReactの依存関係を最新バージョンにアップグレードし、テストと型チェックを実行する。次に、先述のcodemodツールを実行して、非同期になったリクエストスコープAPIの修正を自動化する。その後、cookies()、headers()、params、searchParamsといったリクエストスコープAPIの利用箇所を手動で監査し、すべてawaitが適切に使われているかを確認する。同様に、すべてのfetch()呼び出しとGETルートハンドラーを監査し、それぞれのキャッシュ戦略(強制キャッシュ、再検証設定、あるいはキャッシュしない)を明示的に決定する。開発環境でTurbopackを有効にしてHMRの動作を検証し、認証やパーソナライゼーション機能が期待通りに動作するかを徹底的にテストする。最後に、本番リリース後はバックエンドへのトラフィック増加がないか注意深く監視し、問題が発生した場合は速やかに対応できるよう準備しておくことが重要だ。
結論として、Next.js 15は、Turbopackによる開発速度の向上、React 19のサポート、そしてPartial Prerenderingなどの強力な新機能によって、開発体験とアプリケーションのパフォーマンスの両面で大きなメリットをもたらす。しかし、リクエストスコープAPIの非同期化やキャッシュのデフォルト変更といった、デフォルト設定の意図的な変更がいくつか含まれているため、これらに対する初期の監査と修正作業は避けられない。この初期投資は、開発者がアプリケーションのキャッシュ戦略やデータ取得方法についてより深く考えるきっかけとなり、結果として、より安定し、予測可能な本番動作を実現するための長期的な健全性につながる。Next.js 15へのアップグレードを計画している場合は、これらの変更点に対応するための時間を十分に確保することが、スムーズな移行と最大のメリット享受への鍵となるだろう。