コンテンツにスキップ
ブログに戻る

2024年5月23日 木曜日

Next.js 15 RC

投稿者

Next.js 15 Release Candidate (RC) が利用可能になりました。この初期バージョンでは、今後の安定リリース前に最新の機能をテストできます。

今すぐNext.js 15 RCをお試しください

ターミナル
npm install next@rc react@rc react-dom@rc

React 19 RC

Next.js App Router は、Reactのカナリアチャンネル上に構築されており、v19リリース前にこれらの新しいReact APIを使用し、フィードバックを提供できるようになっています。

Next.js 15 RC は React 19 RC をサポートするようになりました。これには、Actions のようなクライアントおよびサーバー両方のための新機能が含まれます。

以下をお読みください:Next.js 15 アップグレードガイドReact 19 アップグレードガイド、そして React Conf Keynote を視聴して詳細をご確認ください。

注: 一部のサードパーティライブラリは、まだ React 19 と互換性がない場合があります。

React Compiler(実験的)

Meta の React チームが作成した新しい実験的なコンパイラである React Compiler。このコンパイラは、プレーン JavaScript のセマンティクスと React のルールを深く理解することで、コードを深く理解し、コードに自動的な最適化を追加できます。このコンパイラは、useMemouseCallbackなどのAPIを通じて開発者が行う手動のメモ化の量を減らし、コードをよりシンプルで、保守しやすく、エラーを起こしにくくします。

Next.js 15 では、React Compilerのサポートを追加しました。

babel-plugin-react-compilerをインストール

ターミナル
npm install babel-plugin-react-compiler

次に、next.config.jsexperimental.reactCompilerオプションを追加します。

next.config.ts
const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};
 
module.exports = nextConfig;

オプションで、コンパイラを以下のように「オプトイン」モードで実行するように設定できます。

next.config.ts
const nextConfig = {
  experimental: {
    reactCompiler: {
      compilationMode: 'annotation',
    },
  },
};
 
module.exports = nextConfig;

注: React Compiler は現在、Next.js では Babel プラグインを通じてのみ使用可能であり、ビルド時間が遅くなる可能性があります。

以下で React Compiler の詳細を確認してください:React Compiler、および利用可能な Next.js 設定オプション

ハイドレーションエラーの改善

Next.js 14.1 では、エラーメッセージとハイドレーションエラーを改善しました。Next.js 15 では、改善されたハイドレーションエラービューを追加することで、これらの改善を継続しています。ハイドレーションエラーは、エラーのソースコードと問題の対処方法に関する提案を表示するようになりました。

例えば、これは Next.js 14.1 でのエラーメッセージでした。

Hydration error message in Next.js 14.1

Next.js 15 RC では、これを以下のように改善しました。

Hydration error message improved in Next.js 15 RC

キャッシュの更新

Next.js App Router は、意見の分かれるキャッシュのデフォルト設定でリリースされました。これらは、デフォルトで最もパフォーマンスの高いオプションを提供し、必要に応じてオプトアウトできることを目的としていました。

皆様からのフィードバックに基づき、キャッシュヒューリスティック と、Partial Prerendering (PPR) のようなプロジェクトや、fetch を使用するサードパーティライブラリとの相互作用を再評価しました。

Next.js 15 では、fetch リクエスト、GET ルートハンドラー、およびクライアントルーターキャッシュのデフォルト設定を、デフォルトでキャッシュするからデフォルトでキャッシュしないに変更します。以前の動作を維持したい場合は、引き続きキャッシュをオプトインできます。

今後数ヶ月間、Next.js でのキャッシュの改善を継続し、Next.js 15 GA 発表で詳細を共有します。

fetch リクエストはデフォルトでキャッシュされなくなりました

Next.js は、サーバーサイドの fetch リクエストがフレームワークの永続的な HTTP キャッシュとどのようにやり取りするかを構成するために、Web fetch API を使用します。

fetch('https://...', { cache: 'force-cache' | 'no-store' });
  • no-store - リクエストごとにリモートサーバーからリソースを取得し、キャッシュを更新しない
  • force-cache - キャッシュ(存在する場合)またはリモートサーバーからリソースを取得し、キャッシュを更新する

Next.js 14 では、cache オプションが指定されていない場合、動的な関数または動的な設定オプションが使用されていない限り、デフォルトで force-cache が使用されていました。

Next.js 15 では、cache オプションが指定されていない場合、デフォルトで no-store が使用されます。これは、fetch リクエストはデフォルトでキャッシュされないことを意味します。

fetch リクエストのキャッシュは、以下のようにオプトインできます。

  • 単一の fetch コールで cache オプションforce-cache に設定する
  • 単一のルートに対して dynamic ルート設定オプション'force-static' に設定する
  • レイアウトまたはページ内のすべての fetch リクエストを force-cache で使用するようにオーバーライドするには、fetchCache ルート設定オプション'default-cache' に設定する。ただし、明示的に独自の cache オプションを指定した場合はそれが優先されます。

GET ルートハンドラーはデフォルトでキャッシュされなくなりました

Next 14 では、GET HTTP メソッドを使用するルートハンドラーは、動的な関数または動的な設定オプションを使用しない限り、デフォルトでキャッシュされていました。Next.js 15 では、GET 関数はデフォルトでキャッシュされません

export dynamic = 'force-static'のような静的なルート設定オプションを使用して、引き続きキャッシュをオプトインできます。

sitemap.tsopengraph-image.tsxicon.tsx、およびその他のメタデータファイルのような特別なルートハンドラーは、動的な関数または動的な設定オプションを使用しない限り、デフォルトで静的になります。

クライアントルーターキャッシュは、デフォルトでページコンポーネントをキャッシュしなくなりました

Next.js 14.2.0 では、staleTimesフラグを導入し、ルーターキャッシュのカスタム設定を可能にしました。

Next.js 15 では、このフラグは引き続き利用可能ですが、ページセグメントの staleTime0 に設定するというデフォルトの動作を変更します。これは、アプリ内をナビゲートする際に、クライアントがナビゲーションの一部としてアクティブになるページコンポーネントの最新データを常に反映することを意味します。ただし、変更されていない重要な動作もいくつかあります。

  • 共有レイアウトデータは、部分レンダリングをサポートするために、サーバーから再取得されません。
  • ブラウザがスクロール位置を復元できるように、バック/フォワードナビゲーションは引き続きキャッシュから復元されます。
  • Loading.js は 5 分間 (または staleTimes.static 設定の値) キャッシュされたままになります。

以前のクライアントルーターキャッシュの動作をオプトインするには、以下の設定を行います。

next.config.ts
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
    },
  },
};
 
module.exports = nextConfig;

部分プリレンダリングの段階的導入(実験的)

Next.js 14 では、部分プリレンダリング (PPR) を導入しました。これは、同じページで静的レンダリングと動的レンダリングを組み合わせた最適化です。

Next.js は現在、cookies()headers()、およびキャッシュされないデータリクエストのような動的な関数を使用しない限り、デフォルトで静的レンダリングになります。これらのAPIは、ルート全体を動的レンダリングにオプトインします。PPRを使用すると、任意の動的UIをSuspense境界でラップできます。新しいリクエストが来ると、Next.js はすぐに静的な HTML シェルを提供し、その後、同じ HTTP リクエストで動的な部分をレンダリングしてストリーミングします。

段階的導入を可能にするために、特定のレイアウトとページを PPR にオプトインするための experimental_ppr ルート設定オプションを追加しました。

app/page.jsx
import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
 
export const experimental_ppr = true
 
export default function Page() {
  return {
     <>
	     <StaticComponent />
	     <Suspense fallback={...}>
		     <DynamicComponent />
	     </Suspense>
     </>
  };
}

新しいオプションを使用するには、next.config.js ファイルで experimental.ppr 設定を 'incremental' に設定する必要があります。

next.config.ts
const nextConfig = {
  experimental: {
    ppr: 'incremental',
  },
};
 
module.exports = nextConfig;

すべてのセグメントで PPR が有効になったら、ppr 値を true に設定し、アプリ全体と将来のすべてのルートで有効にすることが安全と見なされます。

PPR のロードマップについては、Next.js 15 GA のブログ投稿でさらに詳しく説明します。

以下で Partial Prerendering の詳細を確認してください:Partial Prerendering

レスポンス後にコードを実行する(next/after)(実験的)

ユーザーリクエストを処理する際、サーバーは通常、レスポンスの計算に直接関係するタスクを実行します。しかし、ログ、分析、その他の外部システム同期などのタスクを実行する必要がある場合があります。

これらのタスクはレスポンスに直接関係しないため、ユーザーは完了を待つ必要はありません。レスポンス後に作業を遅延させることは、サーバーレス関数がレスポンスが閉じられた直後に計算を停止するため、課題となります。

after() は、レスポンスがストリーミングを終了した後に処理する作業をスケジュールできるようにする新しい実験的なAPIであり、プライマリレスポンスをブロックせずに二次タスクを実行できるようにします。

使用するには、next.config.jsexperimental.after を追加します。

next.config.ts
const nextConfig = {
  experimental: {
    after: true,
  },
};
 
module.exports = nextConfig;

次に、Server Components、Server Actions、Route Handlers、または Middleware で関数をインポートします。

import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
 
export default function Layout({ children }) {
  // Secondary task
  after(() => {
    log();
  });
 
  // Primary task
  return <>{children}</>;
}

以下で next/after の詳細を確認してください:next/after

create-next-app の更新

Next.js 15 では、create-next-app を新しいデザインで更新しました。

New design for create-next-app in Next.js 15 RC

create-next-app を実行すると、ローカル開発で Turbopack を有効にするかどうかを尋ねる新しいプロンプトが表示されます(デフォルトはいいえ)。

ターミナル
 Would you like to use Turbopack for next dev?  No / Yes

--turbo フラグを使用して Turbopack を有効にできます。

ターミナル
npx create-next-app@rc --turbo

新しいプロジェクトでの開始をさらに容易にするために、CLI に新しい --empty フラグが追加されました。これにより、不要なファイルやスタイルが削除され、最小限の「hello world」ページが生成されます。

ターミナル
npx create-next-app@rc --empty

外部パッケージのバンドル最適化(安定版)

外部パッケージのバンドルは、アプリケーションのコールドスタートパフォーマンスを向上させることができます。App Router では、外部パッケージはデフォルトでバンドルされ、新しい serverExternalPackages 設定オプションを使用して、特定のパッケージをオプトアウトできます。

Pages Router では、外部パッケージはデフォルトでバンドルされませんが、既存の transpilePackages オプションを使用して、バンドルするパッケージのリストを指定できます。この設定オプションでは、各パッケージを指定する必要があります。

App Router と Pages Router の間の設定を統一するために、新しいオプションである bundlePagesRouterDependencies を導入し、App Router のデフォルトの自動バンドルと一致させます。その後、必要に応じて serverExternalPackages を使用して特定のパッケージをオプトアウトできます。

next.config.ts
const nextConfig = {
  // Automatically bundle external packages in the Pages Router:
  bundlePagesRouterDependencies: true,
  // Opt specific packages out of bundling for both App and Pages Router:
  serverExternalPackages: ['package-name'],
};
 
module.exports = nextConfig;

以下で外部パッケージの最適化の詳細を確認してください:optimizing external packages

その他の変更点

  • [破壊的変更] React の最小バージョンは 19 RC になりました。
  • [破壊的変更] next/image: オプションの依存関係として sharp を使用するために squoosh を削除 (PR)
  • [破壊的変更] next/image: デフォルトの Content-Dispositionattachment に変更 (PR)
  • [破壊的変更] next/image: src に先頭または末尾のスペースがある場合にエラーが発生 (PR)
  • [破壊的変更] Middleware: 非推奨の React API のインポートを制限するために react-server 条件を適用 (PR)
  • [破壊的変更] next/font: 外部 @next/font パッケージのサポートを削除 (PR)
  • [破壊的変更] next/font: font-family ハッシュを削除 (PR)
  • [破壊的変更] キャッシュ: force-dynamic は fetch キャッシュに no-store デフォルトを設定します (PR)
  • [破壊的変更] 設定: デフォルトで swcMinify (PR)、missingSuspenseWithCSRBailout (PR)、および outputFileTracing (PR) の動作をデフォルトで有効にし、非推奨のオプションを削除します。
  • [破壊的変更] Speed Insights の自動インストルメンテーションを削除(専用の @vercel/speed-insights パッケージを使用する必要があります)(PR)
  • [破壊的変更] 動的サイトマップルートの .xml 拡張子を削除し、開発と本番環境のサイトマップ URL を一致させます (PR)
  • [改善] メタデータ: Vercel でホストされる場合の metadataBase の環境変数フォールバックを更新 (PR)
  • [改善] optimizePackageImports からの名前空間および名前付きインポートの混在によるツリーシェイクの修正 (PR)
  • [改善] 並列ルート: マッチしないキャッチオールルートにすべての既知のパラメータを渡す (PR)
  • [改善] 設定 bundlePagesExternals は安定し、bundlePagesRouterDependencies に名前が変更されました。
  • [改善] 設定 serverComponentsExternalPackages は安定し、serverExternalPackages に名前が変更されました。
  • [改善] create-next-app: 新しいプロジェクトは、デフォルトですべての .env ファイルを無視します (PR)
  • [ドキュメント] 認証ドキュメントを改善 (PR)
  • [ドキュメント] @next/env パッケージ (PR)

詳細については、アップグレードガイドを参照してください。

コントリビューター

Next.js は、3,000 人以上の個人開発者、Google や Meta のような業界パートナー、そして Vercel のコアチームの共同作業の成果です。このリリースは、以下の方々によって提供されました。

@devjiwonchoi, @ijjk, @Ethan-Arrowood, @sokra, @kenji-webdev, @wbinnssmith, @huozhi, @domdomegg, @samcx, @Jaaneek, @evanwinter, @wyattjoh, @kdy1, @balazsorban44, @feedthejim, @ztanner, @ForsakenHarmony, @kwonoj, @delbaoliveira, @stipsan, @leerob, @shuding, @xiaohanyu, @timneutkens, @dvoytenko, @bobaaaaa, @bgw, @gaspar09, @souporserious, @unflxw, @kiner-tang, @Ehren12, @EffectDoplera, @IAmKushagraSharma, @Auxdible, @sean-rallycry, @Jeffrey-Zutt, @eps1lon, @jeanmax1me, @unstubbable, @NilsJacobsen, @PaulAsjes, @adiguno, @ryan-nauman, @zsh77, @KagamiChan, @steveluscher, @MehfoozurRehman, @vkryachko, @chentsulin, @samijaber, @begalinsaf, @FluxCapacitor2, @lukahartwig, @brianshano, @pavelglac, @styfle, @symant233, @HristovCodes, @karlhorky, @jonluca, @jonathan-ingram, @mknichel, @sopranopillow, @Gomah, @imddc, @notrab, @gabrielrolfsen, @remorses, @AbhiShake1, @agadzik, @ryota-murakami, @rishabhpoddar, @rezamauliadi, @IncognitoTGT, @webtinax, @BunsDev, @nisabmohd, @z0n, @bennettdams, @joeshub, @n1ckoates, @srkirkland, @RiskyMH, @coopbri, @okoyecharles, @diogocapela, @dnhn, @typeofweb, @davidsa03, @imranolas, @lubieowoce, @maxhaomh, @mirasayon, @blvdmitry, @hwangstar156, @lforst, @emmerich, @christian-bromann, @Lsnsh, @datner, @hiro0218, @flybayer, @ianmacartney, @ypessoa, @ryohidaka, @icyJoseph, @Arinji2, @lovell, @nsams, @Nayeem-XTREME, @JamBalaya56562, @Arindam200, @gaojude, @qqww08, @todor0v, @coltonehrman、そして @wiesson に多大な感謝を捧げます!