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

2024年1月18日(木)

Next.js 14.1

投稿者

Next.js 14.1 には、以下の開発者エクスペリエンスの改善が含まれています。

今すぐアップグレードするか、以下から始めましょう。

ターミナル
npx create-next-app@latest

セルフホスティングの改善

Node.js サーバー、Docker コンテナー、または静的エクスポートを使用して Next.js をセルフホストする方法について、より明確にするためのフィードバックをいただきました。以下に関するセルフホスティングのドキュメントを刷新しました。

Next.js 14.1 では、増分静的再生成用のカスタムキャッシュハンドラーと、App Router のより粒度の高いデータキャッシュの提供も安定させました。

next.config.js
module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  cacheMaxMemorySize: 0, // disable default in-memory caching
};

Kubernetes のようなコンテナーオーケストレーションプラットフォームを使用する場合、各ポッドにキャッシュのコピーがあるため、セルフホスティング時にこの構成を使用することが重要です。カスタムキャッシュハンドラーを使用すると、Next.js アプリケーションをホストするすべてのポッド間で一貫性を確保できます。

たとえば、キャッシュされた値を Redis や Memcached などの任意の場所に保存できます。@neshcaRedis キャッシュハンドラーアダプター と例に感謝します。

Turbopack の改善

ローカルでの Next.js 開発の信頼性とパフォーマンスの向上に引き続き注力しています。

  • 信頼性: Turbopack が Next.js 開発テストスイート全体に合格し、Vercel のアプリケーションをドッグフーディング
  • パフォーマンス: Turbopack の初期コンパイル時間と高速リフレッシュ時間の改善
  • メモリ使用量: Turbopack のメモリ使用量の改善

今後リリースされるバージョンで next dev --turbo を安定化させる予定で、引き続きオプトインとなります。

信頼性

Turbopack を使用した Next.js は現在、5,600 件の開発テスト (94%) に合格しており、前回の更新から 600 件増加しました。 areweturboyet.com で進捗状況を確認できます。

vercel.comv0.dev を含む、すべての Vercel の Next.js アプリケーションで next dev --turbo のドッグフーディングを継続しています。これらのアプリケーションに取り組むすべてのエンジニアが、Turbopack を毎日使用しています。

Turbopack を使用した非常に大規模な Next.js アプリケーションの多くの問題を特定して修正しました。これらの修正のために、Next.js の既存の開発テストスイートに新しいテストを追加しました。

パフォーマンス

大規模な Next.js アプリケーションである vercel.com では、以下のような改善が見られました。

  • ローカルサーバーの起動が最大 76.7% 高速化
  • Fast Refresh でのコード更新が最大 96.3% 高速化
  • キャッシュなしでの初期ルートコンパイルが最大 45.8% 高速化(Turbopack にはまだディスクキャッシュがありません)

v0.dev では、React クライアントコンポーネントが Turbopack で検出およびバンドルされる方法を最適化する機会を特定し、初期コンパイル時間が最大 61.5% 高速化されました。このパフォーマンスの向上は vercel.com でも確認されました。

今後の改善

Turbopack には現在、Fast Refresh の増分コンパイル時間を改善するインメモリキャッシュがあります。

ただし、現在、キャッシュは Next.js 開発サーバーを再起動すると保持されません。Turbopack のパフォーマンスに関する次の大きなステップはディスクキャッシュであり、これにより開発サーバーを再起動するときにキャッシュを保持できます。

開発者エクスペリエンスの向上

エラーメッセージと高速リフレッシュの改善

明確なエラーメッセージがローカル開発エクスペリエンスにとってどれほど重要であるかは承知しています。next dev を実行する際に表示されるスタックトレースとエラーメッセージの品質を向上させるために、多くの修正を行いました。

  • 以前は webpack-internal のようなバンドラーエラーを表示していたエラーは、エラーのソースコードと影響を受けるファイルを適切に表示するようになりました。
  • クライアントコンポーネントでエラーが発生し、エディターでエラーを修正した後、高速リフレッシュではエラー画面がクリアされませんでした。ハードリロードが必要でした。これらのインスタンスの多くを修正しました。たとえば、クライアントコンポーネントから metadata をエクスポートしようとする場合などです。

たとえば、以前のエラーメッセージは次のようでした。

An example of an error from a fetch call in Next.js 14.
Next.js 14 での fetch 呼び出しからのエラーの例。

Next.js 14.1 では、これが次のように改善されました。

Errors from fetch calls during rendering now display the source code of the error and the affected file.
レンダリング中の fetch 呼び出しからのエラーは、エラーのソースコードと影響を受けるファイルを表示するようになりました。

window.history.pushState および window.history.replaceState

App Router では、ページをリロードせずにブラウザーの履歴スタックを更新するために、ネイティブの pushState および replaceState メソッドを使用できるようになりました。

pushState および replaceState の呼び出しは Next.js App Router に統合され、usePathname および useSearchParams と同期できます。

これは、フィルター、ソート順、またはリロード時に保持したいその他の情報などの状態を保存するときに、URL をすぐに更新する必要がある場合に役立ちます。

'use client';
 
import { useSearchParams } from 'next/navigation';
 
export default function SortProducts() {
  const searchParams = useSearchParams();
 
  function updateSorting(sortOrder: string) {
    const params = new URLSearchParams(searchParams.toString());
    params.set('sort', sortOrder);
    window.history.pushState(null, '', `?${params.toString()}`);
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Sort Ascending</button>
      <button onClick={() => updateSorting('desc')}>Sort Descending</button>
    </>
  );
}

Next.js での ネイティブ History API の使用方法について詳しくはこちらをご覧ください。

データキャッシュロギング

next dev の実行時に Next.js アプリケーションでキャッシュされたデータの可観測性を向上させるために、logging 設定オプションに多くの改善を加えました。

キャッシュが HIT または SKIP されたかどうかと、要求された完全な URL を表示できるようになりました。

ターミナル
GET / 200 in 48ms
Compiled /fetch-cache in 117ms
 GET /fetch-cache 200 in 165ms
GET https://api.vercel.app/products/1 200 in 14ms (cache: HIT)
Compiled /fetch-no-store in 150ms
 GET /fetch-no-store 200 in 548ms
GET https://api.vercel.app/products/1 200 in 345ms (cache: SKIP)
  Cache missed reason: (cache: no-store)

これは next.config.js で有効にできます。

next.config.js
module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
};

<picture> およびアートディレクションの next/image サポート

Next.js Image コンポーネントは、<Image> を直接使用する必要がない getImageProps() (安定版) を通じて、より高度なユースケースをサポートするようになりました。これには以下が含まれます。

import { getImageProps } from 'next/image';
 
export default function Page() {
  const common = { alt: 'Hero', width: 800, height: 400 };
  const {
    props: { srcSet: dark },
  } = getImageProps({ ...common, src: '/dark.png' });
  const {
    props: { srcSet: light, ...rest },
  } = getImageProps({ ...common, src: '/light.png' });
 
  return (
    <picture>
      <source media="(prefers-color-scheme: dark)" srcSet={dark} />
      <source media="(prefers-color-scheme: light)" srcSet={light} />
      <img {...rest} />
    </picture>
  );
}

getImageProps() について詳しくはこちらをご覧ください。

パラレル & インターセプトされたルート

Next.js 14.1 では、パラレル & インターセプトされたルートに **20 個の改善**を行いました。

過去 2 回のリリースでは、Next.js のパフォーマンスと信頼性の向上に注力してきました。皆様からのフィードバックに基づいて、パラレル & インターセプトされたルート に多くの改善を加えることができました。特に、キャッチオールルートとサーバーアクションのサポートを追加しました。

  • **パラレルルート**を使用すると、同じレイアウト内で 1 つ以上のページを同時または条件付きでレンダリングできます。ダッシュボードやソーシャルサイトのフィードなど、アプリの動的なセクションの場合、パラレルルートを使用して複雑なルーティングパターンを実装できます。
  • **インターセプトされたルート**を使用すると、現在のレイアウト内でアプリケーションの別の部分からのルートを読み込むことができます。たとえば、フィード内の写真をクリックすると、フィードに重ねて写真をモーダルで表示できます。この場合、Next.js は /photo/123 ルートをインターセプトし、URL をマスクして /feed に重ねて表示します。

パラレル & インターセプトされたルート または 例を見る について詳しくはこちらをご覧ください。

その他の改善点

14.0以降、コミュニティから多く投票されたバグをいくつか修正しました。

また、最近、キャッシュについて説明する動画を公開しました。また、App Routerに関する一般的な間違いを説明する動画も公開しました。これらは役立つかもしれません。

  • [ドキュメント] リダイレクトに関する新しいドキュメント
  • [ドキュメント] テストに関する新しいドキュメント
  • [ドキュメント] 本番環境チェックリストを含む新しいドキュメント
  • [機能] next/third-parties<GoogleAnalytics />コンポーネントを追加 (ドキュメント)
  • [改善] create-next-appがより小さく、インストールがより速くなりました (PR)
  • [改善] ネストされたルートでエラーが発生した場合でも、global-errorでキャッチできるようになりました (PR)
  • [改善] サーバーアクションで使用する場合、redirectbasePathを尊重するようになりました (PR)
  • [改善] App Routerでのnext/scriptbeforeInteractiveの使用を修正 (PR)
  • [改善] ルートの起動を高速化するために、@aws-sdklodashを自動的にトランスパイル (PR)
  • [改善] next devnext/fontを使用した際、スタイルなしコンテンツのフラッシュを修正 (PR)
  • [改善] セグメントのエラー境界を越えてnotFoundエラーを伝播 (PR)
  • [改善] Pages Router i18nでロケールドメインからパブリックファイルを提供する問題を修正 (PR)
  • [改善] 無効なrevalidate値が渡された場合にエラーを表示 (PR)
  • [改善] Windowsで作成されたビルドをLinuxマシンで実行した際、パスの問題を修正 (PR)
  • [改善] basePathを使用したマルチゾーンアプリを使用する際のFast Refresh / HMRを修正 (PR)
  • [改善] 終了シグナルからの正常なシャットダウンを改善 (PR)
  • [改善] 異なるルートからインターセプトした場合に、モーダルルートが衝突する問題を修正 (PR)
  • [改善] basePath構成を使用する際のルートインターセプトを修正 (PR)
  • [改善] 不足しているパラレルスロットが404になる場合、警告を表示 (PR)
  • [改善] キャッチオールルートで使用する場合のインターセプトされたルートを改善 (PR)
  • [改善] revalidatePathで使用する場合のインターセプトされたルートを改善 (PR)
  • [改善] パラレルルートでの@childrenスロットの使用を修正しました (PR)
  • [改善] パラレルルートでparamsを使用する際のTypeErrorを修正しました (PR)
  • [改善] デフォルトのパラレルルートに対するキャッチオールルートの正規化を修正しました (PR)
  • [改善] next buildのサマリーでのパラレルルートの表示を修正しました (PR)
  • [改善] インターセプトされたルートを使用する際のルートパラメータを修正しました (PR)
  • [改善] 深くネストされたパラレル/インターセプトされたルートを改善しました (PR)
  • [改善] ルートグループと組み合わされたインターセプトされたルートでの404エラーを修正しました (PR)
  • [改善] サーバーアクション/ルーターキャッシュの再検証を伴うパラレルルートを修正しました (PR)
  • [改善] インターセプトされたルートでのrewritesの使用を修正しました (PR)
  • [改善] サーバーアクションがサードパーティライブラリから動作するようになりました (PR)
  • [改善] Next.jsがESMパッケージ内で使用できるようになりました (PR)
  • [改善] Material UIのようなライブラリ向けのバレルファイルの最適化 (PR)
  • [改善] SuspenseなしでuseSearchParamsを誤って使用するとビルドが失敗するようになりました (PR)

貢献者

Next.jsは、3,000人を超える個々の開発者、GoogleやMetaのような業界パートナー、そしてVercelのコアチームによる共同作業の成果です。 GitHub DiscussionsReddit、そして Discordでコミュニティに参加してください。

このリリースは以下の方々によってもたらされました

そして、貢献者の皆様: @OlehDutchenko, @eps1lon, @ebidel, @janicklas-ralph, @JohnPhamous, @chentsulin, @akawalsky, @BlankParticle, @dvoytenko, @smaeda-ks, @kenji-webdev, @rv-david, @icyJoseph, @dijonmusters, @A7med3bdulBaset, @jenewland1999, @mknichel, @kdy1, @housseindjirdeh, @max-programming, @redbmk, @SSakibHossain10, @jamesmillerburgess, @minaelee, @officialrajdeepsingh, @LorisSigrist, @yesl-kim, @StevenKamwaza, @manovotny, @mcexit, @remcohaszing, @ryo-manba, @TranquilMarmot, @vinaykulk621, @haritssr, @divquan, @IgorVaryvoda, @LukeSchlangen, @RiskyMH, @ash2048, @ManuWeb3, @msgadi, @dhayab, @ShahriarKh, @jvandenaardweg, @DestroyerXyz, @SwitchBladeAK, @ianmacartney, @justinh00k, @tiborsaas, @ArianHamdi, @li-jia-nan, @aramikuto, @jquinc30, @samcx, @Haosik, @AkifumiSato, @arnabsen, @nfroidure, @clbn, @siddtheone, @zbauman3, @anthonyshew, @alexfradiani, @CalebBarnes, @adk96r, @pacexy, @hichemfantar, @michaldudak, @redonkulus, @k-taro56, @mhughdo, @tknickman, @shumakmanohar, @vordgi, @hamirmahal, @gaspar09, @JCharante, @sjoerdvanBommel, @mass2527, @N-Ziermann, @tordans, @davidthorand, @rmathew8-gh, @chriskrogh, @shogunsea, @auipga, @SukkaW, @agustints, @OXXD, @clarencepenz, @better-salmon, @808vita, @coltonehrman, @tksst, @hugo-syn, @JakobJingleheimer, @Willem-Jaap, @brandonnorsworthy, @jaehunn, @jridgewell, @gtjamesa, @mugi-uno, @kentobento, @vivianyentran, @empflow, @samennis1, @mkcy3, @suhaotian, @imevanc, @d3lm, @amannn, @hallatore, @Dylan700, @mpsq, @mdio, @christianvuerings, @karlhorky, @simonhaenisch, @olci34, @zce, @LavaToaster, @rishabhpoddar, @jirihofman, @codercor, @devjiwonchoi, @JackieLi565, @thoushif, @pkellner, @jpfifer, @quisido, @tomfa, @raphaelbadia, @j9141997, @hongaar, @MadCcc, @luismulinari, @dumb-programmer, @nonoakij, @franky47, @robbertstevens, @bryndyment, @marcosmartini, @functino, @Anisi, @AdonisAgelis, @seangray-dev, @prkagrawal, @heloineto, @kn327, @ihommani, @MrNiceRicee, @falsepopsky, @thomasballinger, @tmilewski, @Vadman97, @dnhn, @RodrigoTomeES, @sadikkuzu, @gffuma, @Schniz, @joulev, @Athrun-Judah, @rasvanjaya21, @rashidul0405, @nguyenbry, @Mwimwii, @molebox, @mrr11k, @philwolstenholme, @IgorKowalczyk, @Zoe-Bot, @HanCiHu, @JackHowa, @goncy, @hirotomoyamada, @pveyes, @yeskunall, @ChendayUP, @hmaesta, @ajz003, @its-kunal, @joelhooks, @blurrah, @tariknh, @Vinlock, @Nayeem-XTREME, @aziyatali, @aspehler, そして @moka-ayumu。