Web開発
Next.js 16.4
要約
Next.js 16.4では、キャッシュコンポーネントと呼ばれる新しいプログラミングモデルがデフォルトで有効になり、すべてのNext.jsアプリで推奨されるようになりました。このモデルは、初期ロードの高速化、サーバーレンダリングアプリでの即時クライアントナビゲーション、キャッシュのオプトイン化・宣言的・コンポーザブルな管理を実現します。また、ensureStaticによる静的ページの保証や、prefetchからのコンテンツ除外機能なども追加されています。
全文翻訳
ブログに戻る火曜日、2026年10月6日Next.js 16.4投稿者: 9+Next.jsチーム17人のメンバー16.xリリースを通じて、App Routerの当初からの多くの不満に対処する新しいプログラミングモデルを導入しました。これは、パーソナライズされたページでも高速な初期ロードを実現します。サーバーレンダリングされたアプリに即時のクライアントナビゲーションを提供します。キャッシュをオプトイン、宣言的、コンポーザブルにします。この新しいプログラミングモデルはキャッシュコンポーネントと呼ばれ、Next.js 17ではデフォルトになります。このリリース以前は、以前のモデルと同じコストとパフォーマンスの保証を達成できないケースがあったため、普遍的に推奨していませんでした。このリリースには、それらのギャップを埋める重要な機能が含まれています。Next.js 16.4から、キャッシュコンポーネントをすべてのNext.jsアプリにとって最良の選択肢として推奨できることを嬉しく思います。本日より、create-next-appで作成されたすべての新しいアプリは、デフォルトでキャッシュコンポーネントが有効になります。新規プロジェクトは、予約なしで新しいモデルのすべてのメリットを享受できます。既存のアプリについては、コードベースが新しいモデルに移行するのを支援するための、より優れたエージェントツールに投資してきました。新しいnext upgrade --agentコマンドは、エージェントにアプリのアップグレードに関するバージョン固有のガイダンスを提供し、専用のスキルは、キャッシュコンポーネントを採用するために必要なリファクタリングをエージェントが支援します。Next.js 16.4には、すべてのNext.jsアプリ向けのいくつかのすぐに使える改善も含まれており、開発時のメモリ使用量とディスクサイズの削減、コンパイル時間の短縮、プロダクションバンドルの小型化、React 19.3などが含まれます。ここでは、キャッシュコンポーネントから始まるこのリリースで期待できることの概要をすべて紹介します。キャッシュコンポーネントとは何ですか?キャッシュコンポーネントは、コンポーネントツリーの特定のセクションをキャッシュ可能としてマークできる機能のスイートです。「use cache」を、Cache-Control HTTPヘッダーのコンポーネントレベルのバージョンと考えてください。import { cacheLife } from 'next/cache';export default async function DashboardPage() { const currentUser = await getCurrentUser(); return ( <div> <p>Welcome, {currentUser.name}</p> <Suspense fallback={<Loading />}> <Projects userId={currentUser.id} /> </Suspense> </div> ); }async function Projects({ userId }) { 'use cache'; cacheLife('hours'); const projects = await db.query.projects.findMany({ where: eq(projectsTable.userId, userId), }); return ( <div> {projects.map((project) => ( <p key={project.id}>{project.name}</p> ))} </div> ); }Next.jsは、ページをレンダリングする際にこれらの「use cache」アノテーションを解釈し、ブラウザ(クライアントナビゲーション中)およびオプションでサーバー(サーバーレンダリング中、またはビルド中の事前レンダリング)でコンポーネントのUIをキャッシュします。これらのコンポーザブルなアノテーションにより、単一のページ内でクライアントサイドキャッシュ、完全にプラグ可能なサーバーサイドキャッシュ、およびリクエストタイムレンダリングを混在させることができ、以前のApp Routerバージョンの暗黙的なキャッシュ動作を置き換えます。キャッシュコンポーネントの詳細については、キャッシュに関するガイドをお読みください。キャッシュコンポーネントの新規事項この投稿では、「キャッシュコンポーネント」という用語は新しいプログラミングモデルを指します。これは、Next.jsの設定で2つのフラグを有効にすることで、今日から使用できます。next.config.tsimport type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, partialPrefetching: true, }; export default nextConfig;キャッシュコンポーネントは、部分プリフェッチなしで最初にリリースされましたが、現在はモデルの一部と見なされています。部分プリフェッチについては、以前のリリース投稿で詳しく説明しています。次に、16.4のキャッシュコンポーネントの新機能を紹介します。シェル、プリフェッチ、またはページの静的化の保証「use cache」の代表的な機能の1つは、単一のサーバーレスポンスで静的コンテンツと動的コンテンツをストリーミングするページを構築できることです。たとえば、現在ログインしているユーザーのアバターを、それ以外は静的に事前レンダリングされたブログ投稿と組み合わせることができます。export default function Page() { return ( <> <UserAvatar /> <Content /> </> ); } // リクエスト時にレンダリングされるコンポーネントasync function UserAvatar() { const currentUser = await getCurrentUser(); // ... } // 静的に事前レンダリングされるコンポーネントasync function Content() { 'use cache'; await fetch('...'); // ... }Next.jsは、キャッシュから事前レンダリングされたブログ投稿(アプリの/publicフォルダやCDNなど)を提供し、リクエスト時にUserAvatarをレンダリングできます。すべて同じHTTPレスポンスから行われます。この柔軟性により、速度やダイナミズムを犠牲にすることなく、洗練されたUIを持つアプリを構築できます。しかし、完全に静的なページを持つアプリを構築したい場合もあります。そのような場合、1つの動的なコンポーネントが、最適化されたサイトのパフォーマンスやコスト特性を低下させる可能性があります。Next.js 16.4では、ensureStaticが、ルートのシェル、プリフェッチ、または完全なナビゲーションが静的であることを保証する簡単な方法を提供します。意図しないコンピューティングを回避し、サーバーコストを抑えたいアプリの場合、これにより、動的なコンポーネントがルートに誤って混入するのを防ぐことができます。たとえば、上記の例のブログ投稿ページを常に静的にし、UserAvatarのような動的なコンポーネントを追加できないようにしたい場合、ルートにexport const ensureStaticを追加できます。export const ensureStatic = 'navigation';export default function Page() { return ( <> <UserAvatar /> {/* 🔴 このコンポーネントはビルドに失敗します */} <Content /> </> ); }ensureStaticを「navigation」に設定すると、動的なコンテンツがこのページに含まれている場合、Next.jsはビルドを失敗させ、このルートへのナビゲーションがリクエスト時にレンダリングされないことを保証します。「navigation」は最も制限の厳しい形式ですが、より細かい制御が必要な場合は、ensureStaticを「prefetch」(明示的なプリフェッチを持つリンクのみが静的コンテンツを取得することを保証するため)または「shell」(ルートが最初に検出されたときに静的コンテンツのみが取得されることを保証するため)に設定することもできます。個々のページで使用するのに加えて、レイアウトにensureStaticを追加して、そのレイアウト内のすべてのページに同じ保証を適用することもできます。たとえば、ルートレイアウトにensureStatic = 'navigation'を追加して、サイトのすべてのページナビゲーションが静的であることを簡単に保証できます。// app/layout.tsx export const ensureStatic = 'navigation'; export default async function RootLayout({ children }) { // ... }その後、特定のページが動的なコンテンツを必要とするようになった場合、ネストされたレイアウトにそれをプッシュダウンできます。多くの動的なアプリはこの機能を使用しませんが、eコマースストア、マーケティングページ、ブログなどの最適化されたサイトでは、ensureStaticは意図しないリクエストタイムレンダリングを防ぐための簡単な方法です。ページを静的に保つこととensureStatic設定の詳細をご覧ください。プリフェッチからのコンテンツの除外プリフェッチは、Next.jsアプリケーションのユーザーエクスペリエンスを向上させる強力な方法です。<Link prefetch>またはuseRouter().prefetch()を使用すると、実際のナビゲーションが行われる前にページのキャッシュされたUIを事前レンダリングすることで、ローディング状態を排除できます。たとえば、簡単なメールアプリを見てみましょう。各メッセージへのリンクをレンダリングする受信トレイを次に示します。async function Inbox() { const messages = await db.query.messages.findMany(); return ( <nav> {messages.map((message) => ( <Link href={`/message/${message.id}`} key={message.id} > {message.subject} </Link> ))} </nav> ); }そして、初めてメッセージスレッドをロードするときにスピナーを表示し、その後、後続の訪問のためにブラウザにキャッシュするメッセージページを次に示します。// app/message/[id]/page.jsx export default function Page({ params }) { return ( <Suspense fallback={<Spinner />}> {params.then(({ id }) => ( <Message id={id} /> ))} </Suspense> ); }async function Message({ id }) { const [message, thread] = await Promise.all([ getMessage(id), getThread(id) ]); return ( <> <p>{message.subject}</p> <div>{message.body}</div> {thread.map((message) => ( <div key={message.id}>{message.body}</div> ))} </> ); }async function getMessage(id) { 'use cache'; return db.query.messages.findFirst({ where: eq(messages.id, id) }); }async function getThread(id) { 'use cache'; return db.quer