➡️

Next.js 15 RC 和訳

2024/05/24に公開

https://nextjs.org/blog/next-15-rc

雑に翻訳しました。
意訳がめちゃくちゃ含まれているので注意です。


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

  • React: React 19 RCをサポート。React Compiler (Experimental)の登場及び、ハイドレーションエラーの改善。
  • Caching: fetchリクエスト、GETルートハンドラー、クライアントナビゲーションはデフォルトではキャッシュされなくなりました。
  • Partial Prerendering (Experimental): PPRをオプトインする設定をLayout及びPageに追加しました。
  • next/after (Experimental): レスポンスのストリーミングを終了後にコードを実行する新しいAPIを追加しました。
  • create-next-app: 初期ページのデザインが更新とTurobpackを利用する為のフラグが追加されました。
  • Bundling external packages (Stable): AppRouter及びPageRouterの構成オプションが追加されました。

今日からNext.js 15 RCを試すことが出来ます。

npm install next@rc react@rc react-dom@rc

React 19 RC

Next.js AppRouterは、フレームワーク用のReact canary channel上に構築されており、開発者はv19リリース前にこれらの新しいReact APIを使用し、フィードバックを提供することができます。

Next.js 15 RCは、Actionsのようなクライアントとサーバーの両方の新機能を含むReact 19 RCをサポートしています。

詳しくは、Next.js 15アップグレードガイドReact 19アップグレードガイドReact Conf Keynoteをご覧ください。

React Compiler (Experimental)

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

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

まずは babel-plugin-react-compiler をインストールします:

npm install babel-plugin-react-compiler

次に、next.config.jsにexperimental.reactCompilerオプションを追加します:

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

以下のように「オプトイン」モードで実行するようにコンパイラーを設定することもできます:

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

React Compilerの詳細と、利用可能なNext.jsの設定オプションについては、こちらをご覧ください。

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

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

たとえば、これはNext.js 14.1で表示されていたハイドレーションのエラーメッセージです:

Next.js 15 RCではこのように改善されました:


Caching

Next.js AppRouterは、デフォルトでキャッシュが有効な状態で導入されました。
これらは、デフォルトで最もパフォーマンスの高いオプションを提供し、必要に応じてオプトアウトできるように設計されています。

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

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

Next.jsのキャッシュは今後も改善され続けます。詳細はNext.js 15 GAのアナウンスでお伝えします。

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

Next.jsは、Web fetch APIのキャッシュオプションを使用して、サーバー側のフェッチリクエストがフレームワークの永続的なHTTPキャッシュとどのように相互作用するかを設定します:

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

Next.js 14では、キャッシュオプションが提供されていない場合、dynamic関数またはdynamicコンフィグオプションが使用されていない限り、デフォルトでforce-cacheが使用されました。

Next.js 15では、キャッシュオプションが提供されない場合、デフォルトでno-storeが使用されます。つまり、fetchリクエストはデフォルトではキャッシュされません。

fetchリクエストのキャッシュを有効にするには、以下の方法があります:

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にします。
これは、アプリをナビゲートすると、ナビゲーションの一部としてアクティブになったページコンポーネントの最新データが常にクライアントに反映されることを意味します。
しかし、重要な動作は変更されません:

  • Partial Renderingを引き続きサポートするため、共有レイアウトデータはサーバーからリフェッチされません。
  • ブラウザがスクロール位置を復元できるように、戻る/進むナビゲーションはキャッシュから復元されます。
  • loading.jsは5分間キャッシュされます(またはconfig.experimental.staleTimes.staticの値)。

以下の設定を行うことで、以前のクライアントルーターキャッシュの動作に切り替えることができます:

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

Partial Prerendering (Experimental)の段階的な導入

Next.js 14では、同じページで静的レンダリングと動的レンダリングを組み合わせる最適化であるPartial Prerendering (PPR)を導入しました。

Next.jsでは現在、cookies(), headers()、キャッシュされないデータ要求などのdynamic関数を使用しない限り、デフォルトで静的レンダリングが行われます。
これらのAPIは、動的レンダリングへのルート全体を選択します。PPRを使えば、動的なUIをサスペンス境界でラップできます。
新しいリクエストが来ると、Next.js はすぐに静的な HTMLシェルを提供し、同じHTTPリクエストで動的な部分をレンダリングしてストリーミングします。

段階的な導入を可能にするため、特定のLayoutとPageをPPRにオプトインするためのルート設定オプションにexperimental_pprを追加しました:

app/page.tsx
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.pprincrementalに設定する必要があります。:

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

すべてのセグメントでPPRが有効になったら、pprtrueに設定し、アプリ全体と将来のすべてのルートで有効にするのが安全だと考えられます。

PPRのロードマップについては、Next.js 15 GAのブログポストで詳しくご紹介します。

Partial Prerenderingの詳細については、こちらをご覧ください。


next/afterによるレスポンス後のコード実行 (Experimental)

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

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

after()はこの問題を解決する新しい実験的なAPIで、レスポンスのストリーミングが終了した後に処理する作業をスケジュールできるようにし、プライマリレスポンスをブロックすることなくセカンダリタスクを実行できるようにします。

新しいAPIを使用するには、next.config.jsexperimental.afterを追加します:

next.config.js
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の詳細については、こちらをご覧ください。


create-next-appの更新

Next.js 15では、create-next-appを新しいデザインでアップデートしました。

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

✔ 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

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

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

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

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

next.config.js
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;

外部パッケージのバンドル最適化についての詳細は、こちらをご覧ください。

PrAha

Discussion