➡️

Next.js 14 和訳

2023/10/27に公開

https://nextjs.org/blog/next-14

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


Next.js Confで発表したとおり、Next.js 14 は、下記の点に最も重点を置いたリリースです。

  • Turbopack : App & Pages Router で 5,000種のテストに合格
    • ローカルサーバーの起動が53%高速化
    • Fast Refreshによるコード更新時の反映速度が94%高速化
  • Server Actions (Stable) : Progressive EnhancementなMutationを実現する
    • キャッシュと再検証の統合
    • シンプルな関数呼び出し、またフォームとネイティブに連動
  • Partial Prerendering (Preview) : 高速な初期静的レスポンス + 動的コンテンツのストリーミング
  • Next.js Learn (New) : App Router、認証、データベースなどを教える無料コース。

今すぐアップグレードするか、次のコマンドで新規作成出来ます。

npx create-next-app@latest

Next.js Compiler: Turbocharged

Next.js 13以降、私達はNext.jsのPagesRouterとAppRouterの両方で、ローカル開発のパフォーマンスを向上させるように取り組んできました。

以前は、この取り組みをサポートするためにnext devやNext.jsの他の部分を書き直していました。しかし、後に私たちはより段階的なアプローチに変更しました。これは、私たちのRustベースのコンパイラが近いうちに安定性に達することを意味し、今後全てのNext.jsの機能をサポートすることに焦点を当てています。

next devに関する5000件の統合テストが、基盤となるRustエンジンであるTurbopackで現在合格しています。これらのテストには、7年分のバグ修正と再現テストが含まれています。

大規模なNext.jsアプリケーションであるvercel.comでテストしている間、下記の事を確認しました。

  • ローカルサーバーの起動が53%高速化
  • Fast Refreshによるコード更新時の反映速度が94%高速化

このベンチマークは、大規模なアプリケーション(および大規模なモジュールグラフ)を使用する際に期待されるパフォーマンスの実験的な結果です。現在、next devのテストの90%が合格しているため、next dev --turboを使用すると、より高速で信頼性の高いパフォーマンスを一貫して確認できるはずです。

100%のテストに合格したら、次回のマイナーリリースでTurbopackを安定版に移行します。また、カスタムコンフィグやエコシステムプラグインのためのWebpackの使用も引き続きサポートします。

テストの合格率はareweturboyet.comで確認できます。


Forms and Mutations

Next.js 9では、フロントエンドのコードと一緒にバックエンドのエンドポイントを素早く構築できるAPI Routesが導入されました。

たとえば、api/ディレクトリに新しいファイルを作成します。

import type { NextApiRequest, NextApiResponse } from 'next';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const data = req.body;
  const id = await createItem(data);
  res.status(200).json({ id });
}

そして、クライアント側では、ReactでonSubmitのようなイベントハンドラを使って、API Routeをfetchすることができます。

import { FormEvent } from 'react';
 
export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData = new FormData(event.currentTarget);
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // Handle response if necessary
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

Next.js 14では、データの変更を簡素化することで開発者のエクスペリエンスを向上させたいと考えています。さらに、ユーザーが遅いネットワーク接続を持っている場合や、低性能なデバイスからフォームを送信する際のユーザーエクスペリエンスを向上させたいと考えています。

Server Actions (Stable)

API Routesを手動で作成する必要がないとしたらどうでしょうか?
その代わりに、サーバー上で安全に実行される関数を定義し、Reactコンポーネントから直接呼び出すことができます。

App Routerは、フレームワークが新機能を採用するために安定したReactCanaryの元で構築されています。Next.js 14では、現在最新のReactCanaryにアップグレードされており、安定したServer Actionsが含まれています。

以前のPages Routerの例は、1つのファイルに簡略化できます

export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id = await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

過去にサーバー中心のフレームワークを使用したことのある開発者にとって、Server Actionsは馴染みがあるはずです。これはフォームやFormData Web APIなどのウェブの基本に基づいて構築されています。

フォームからServer Actionsを使用することは、Progressive Enhancementに役立ちますが、必須ではありません。フォームを介さずに、関数として直接呼び出すこともできます。TypeScriptを使用する場合は、クライアントとサーバーの間で完全にE2Eの型安全性が確保されます。

データの変更、ページの再レンダリング、リダイレクトを1回のネットワーク・ラウンドトリップで行うことができるため、上流のプロバイダーが遅い場合でも、正しいデータがクライアントに表示されます。さらに、異なるアクションを構成して再利用することができ、同じルート内に多くの異なるアクションを含むことができます。

キャッシュ、再検証、リダイレクト、その他

Server Actionsは、App Router自体に深く統合されており、下記のことが可能です。

  • revalidatePath()revalidateTag()でキャッシュされたデータを再検証する。
  • redirect()で異なるルートにリダイレクトする。
  • cookies()によるクッキーの設定と読み込み。
  • useOptimistic()による楽観的なUI更新の処理。
  • useFormState()でサーバからのエラーを捕捉して表示する。
  • useFormStatus()でクライアントの読み込み状態を表示する。

フォームとServer Actionsによる変更、または、Server ComponentsとServer Actionsのセキュリティ モデルとベストプラクティスについては、こちらを参照してください。


Partial Prerendering (Preview)

Next.jsで取り組んでいる、高速な初期静的レスポンスを持つ動的コンテンツのためのコンパイラ最適化である「Partial Prerendering」のPreviewを共有したいと思います。

Partial Prerenderingは、サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、およびインクリメンタルな静的再検証(ISR)に対する10年にわたる研究と開発に基づいて構築されています。

Motivation

皆さんのご意見をお聞きしました。現在、ランタイム、設定オプション、レンダリング方法など、考慮しなければならないことが多すぎます。静的なスピードと信頼性を求める一方で、完全に動的でパーソナライズされたレスポンスもサポートしたいと考えています。

グローバルに優れたパフォーマンスを発揮し、パーソナライズを実現するためには、複雑さを犠牲にするべきではありません。

私たちの課題は、開発者が学ぶべき新しいAPIを導入することなく、既存のモデルを簡素化し、より良い開発者体験を生み出すことでした。サーバーサイドコンテンツの部分的なキャッシュはこれまでもありましたが、これらのアプローチは、私たちが目指す開発者体験とコンポーザビリティの目標を満たす必要があります。

Partial Prerenderingには新しいAPIを覚える必要はありません。

Built on React Suspense

Partial PrerenderingはSuspense Boundaryにより定義されます。その仕組みは次のとおりです。次のようなeコマースページを考えてみましょう。

export default function Page() {
  return (
    <main>
      <header>
        <h1>My Store</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}

Partial Prerenderingを有効にすると、このページは<Suspense />の境界に基づいて静的なシェルを生成します。React Suspenseのfallbackは事前にレンダリングされます。

シェル内のSuspenseフォールバックは、その後、Cookieを読み取ってカートを決定したり、ユーザーに基づいてバナーを表示したりするような、動的なコンポーネントに置き換えられます。

リクエストが行われると、静的なHTMLシェルが即座に提供されます。

<main>
  <header>
    <h1>My Store</h1>
    <div class="cart-skeleton">
      <!-- Hole -->
    </div>
  </header>
  <div class="banner" />
  <div class="product-list-skeleton">
    <!-- Hole -->
  </div>
  <section class="new-products" />
</main>

<ShoppingCart />はユーザーセッションをCookieから読み取るので、このコンポーネントは静的シェルと同じHTTPリクエストの一部としてストリームされます。追加のネットワークラウンドトリップは必要ありません。

import { cookies } from 'next/headers'
 
export default function ShoppingCart() {
  const cookieStore = cookies()
  const session = cookieStore.get('session')
  return ...
}

さらに詳細な静的シェルを作成するには、Suspense Boundaryを追加する必要があるかもしれません。しかし、現在すでにloading.jsを使用している場合、これは暗黙のSuspense Boundaryであるため、静的シェルを生成するために変更は必要ありません。

近日公開

Partial Prerenderingは現在アクティブに開発中です。今後のマイナーリリースで、さらなるアップデートをお伝えする予定です。


Metadataの改善

ページのコンテンツがサーバーからストリーミングされる前に、ビューポート、カラースキーム、テーマに関する重要なメタデータをまずブラウザに送信する必要があります。

これらのメタタグが最初のページコンテンツと一緒に送信されるようにすることで、スムーズなユーザーエクスペリエンスを実現し、テーマカラーの変更によってページがちらついたり、ビューポートの変更によってレイアウトがずれたりするのを防ぎます。

Next.js 14では、ブロッキングと非ブロッキングのメタデータを切り離しました。メタデータの一部はブロッキングであり、非ブロッキングのメタデータが静的シェルの提供を妨げないようにしたいと考えています。

以下のメタデータオプションは現在非推奨となり、将来のメジャーバージョンからは削除される予定です。

  • viewport: ビューポートの初期ズームとその他のプロパティを設定します。
  • colorScheme: ビューポートのサポートモード(明暗)を設定します。
  • themeColor: ビューポートの周りのクロム(ブラウザの枠など)がレンダリングされる色を設定します。

Next.js 14からは、これらのオプションに代わる新しいオプションviewportとgenerateViewportがあります。他のすべてのメタデータオプションは変わりません。

今日からこれらの新しいAPIを採用することができます。既存のメタデータオプションは引き続き使用できます。


Next.js Learn Course

本日、Next.js Learnの新しい無料コースをリリースしました。

  • Next.js App Router
  • スタイリングとTailwind CSS
  • フォントと画像の最適化
  • レイアウトとページの作成
  • ページ間の移動
  • Postgresデータベースのセットアップ
  • Server Componentsによるデータの取得
  • 静的レンダリングと動的レンダリング
  • ストリーミング
  • 部分的なプリレンダリング (オプション)
  • 検索とページネーションの追加
  • データの変更
  • エラー処理
  • アクセシビリティの向上
  • 認証の追加
  • メタデータの追加

Next.js Learnは何百万もの開発者にフレームワークの基礎を教えてきました。そして、私たちは新しい追加のコースについてのあなたのフィードバックを楽しみにしています。コースを受講するには、nextjs.org/learnにアクセスしてください。


その他の変更

  • [Breaking] Node.jsの最小バージョンは18.17になりました。
  • [Breaking] next-swcビルド用のWASMターゲットを削除しました。(PR
  • [Breaking] @next/fontのサポートを廃止し、next/fontが採用されました。 (Codemod)
  • [Breaking] ImageResponseのインポートをnext/serverからnext/ogに変更しました。 (Codemod)
  • [Breaking] exportコマンド非推奨となりました、代わりにoutput: 'export'を使用してください。(Docs)
  • [Deprecation] next/imageonLoadingCompleteは非推奨となり、onLoadが採用されました。
  • [Deprecation] next/imagedomainsは廃止され、remotePatternsが使われるようになりました。
  • [Feature] fetchのキャッシングに関するより詳細なロギングが有効になりました。(Docs)
  • [Improvement] 基本的なcreate-next-appアプリケーションの関数サイズを80%縮小
  • [Improvement] エッジ・ランタイムを開発で使用する際のメモリ管理の強化
PrAha

Discussion