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

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など、どこにでも保存できます。Redisキャッシュハンドラアダプターと例を提供してくれた@neshcaに感謝します。Redisキャッシュハンドラアダプターと例。

Turbopackの改善

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

  • 信頼性: TurbopackがNext.js開発テストスイート全体をパスし、Vercelのアプリケーションでドッグフーディングを実施。
  • パフォーマンス: Turbopackの初回コンパイル時間とFast Refresh時間の改善。
  • メモリ使用量: Turbopackのメモリ使用量の改善。

next dev --turboは、引き続きオプトインとして、今後のリリースで安定化する予定です。

信頼性

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

vercel.comおよびv0.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のパフォーマンスの次の大きなステップはディスクキャッシングであり、これにより開発サーバーの再起動時にキャッシュが保持されるようになります。

開発者体験の改善

エラーメッセージとFast Refreshの改善

明確なエラーメッセージがローカル開発体験にいかに重要であるか、私たちは認識しています。next devの実行時に表示されるスタックトレースとエラーメッセージの品質を向上させるため、いくつかの修正を行いました。

  • 以前はwebpack-internalのようなバンドラエラーを表示していたエラーが、適切にエラーのソースコードと影響を受けるファイルを表示するようになりました。
  • クライアントコンポーネントでエラーが発生し、それをエディタで修正した後、Fast Refreshではエラー画面がクリアされませんでした。手動での再読み込みが必要でした。これらのインスタンスのいくつかを修正しました。例えば、クライアントコンポーネントからmetadataをエクスポートしようとする場合などです。

例えば、これが以前のエラーメッセージでした。

An example of an error from a fetch call in Next.js 14.
Next.js 14でのフェッチ呼び出しによるエラーの例。

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

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

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,
    },
  },
};

next/image<picture>とアートディレクションをサポート

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 devおよびnext/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)
  • [改善] useSearchParamsSuspenseなしで不正に使用された場合、ビルドが失敗するようになりました (PR)

貢献者

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

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

そして、以下の貢献者の方々: @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, and @moka-ayumu.