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

2024年4月11日 木曜日

Next.js 14.2

投稿者

Next.js 14.2 には、開発、本番、およびキャッシュの改善が含まれています。

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

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

開発用 Turbopack (リリース候補)

過去数ヶ月間、Turbopack によるローカル開発パフォーマンスの向上に取り組んできました。バージョン 14.2 では、ローカル開発用の Turbopack リリース候補が利用可能になりました。

  • 統合テスト の 99.8% が現在通過しています。
  • Next.js アプリケーションで使用される上位 300 の npm パッケージが Turbopack でコンパイルできることを確認しました。
  • すべての Next.js の例 は Turbopack で動作します。
  • 高速な CSS バンドラーおよびミニファイアである Lightning CSS を統合しました。

Vercel のアプリケーションで Turbopack を広範にテストしています。例えば、大規模な Next.js アプリケーションである vercel.com では、以下のような結果が得られました。

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

Turbopack は引き続きオプトインであり、以下のコマンドで試すことができます。

ターミナル
next dev --turbo

今後は、メモリ使用量の改善、永続キャッシュの実装、および next build --turbo に注力していきます。

  • メモリ使用量 - メモリ使用量を調査するための低レベルツールを構築しました。パフォーマンスメトリクスと広範なメモリ使用量情報を含むトレースを生成できるようになりました。これらのトレースにより、アプリケーションのソースコードにアクセスせずにパフォーマンスとメモリ使用量を調査できます。
  • 永続キャッシュ - 最適なアーキテクチャオプションも検討しており、今後のリリースで詳細を共有する予定です。
  • next build - Turbopack はまだビルドには利用できませんが、テストの 74.7% はすでに通過しています。進捗状況は areweturboyet.com/build で確認できます。

Turbopack での サポートされている機能 および サポートされていない機能 のリストについては、ドキュメントを参照してください。

ビルドおよび本番環境の改善

Turbopack によるバンドル改善に加えて、すべての Next.js アプリケーション (Pages および App Router の両方) の全体的なビルドおよび本番環境パフォーマンスの改善に取り組んできました。

ツリーシェイキング

サーバーコンポーネントとクライアントコンポーネントの境界線における不要なエクスポートのツリーシェイキングを可能にする最適化を特定しました。例えば、"use client" を含むファイルから単一の Icon コンポーネントをインポートしても、そのパッケージの他のすべてのアイコンは含まれなくなりました。これにより、本番環境の JavaScript バンドルサイズを大幅に削減できます。

react-aria-components のような人気のライブラリでこの最適化をテストしたところ、最終的なバンドルサイズが -51.3% 削減されました。

注意: この最適化は、現在のところバレルファイルでは機能しません。それまでは、optimizePackageImports 設定オプションを使用できます。

next.config.ts
module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
};

ビルドメモリ使用量

非常に大規模な Next.js アプリケーションでは、本番ビルド中にメモリ不足 (OOM) クラッシュが発生することがありました。ユーザーレポートや再現手順を調査した結果、根本的な問題は過剰なバンドルとミニファイ(Next.js が重複を含む、より少ない、より大きな JavaScript ファイルを作成していた)であると特定しました。これらのケースに対応するため、バンドルロジックをリファクタリングし、コンパイラを最適化しました。

初期テストによると、最小限の Next.js アプリケーションでは、メモリ使用量とキャッシュファイルサイズが平均で 2.2GB から 190MB 未満に減少しました。

メモリパフォーマンスのデバッグを容易にするために、next build--experimental-debug-memory-usage フラグを導入しました。詳細については、ドキュメントをご覧ください。

CSS

ページ間をナビゲートする際にスタイルが競合するのを避けるため、本番 Next.js ビルド中の CSS 最適化方法を更新し、CSS をチャンク化しました。

CSS チャンクの順序とマージは、インポート順によって定義されるようになりました。例えば、base-button.module.csspage.module.css より前に配置されます。

base-button.tsx
import styles from './base-button.module.css';
 
export function BaseButton() {
  return <button className={styles.primary} />;
}
page.tsx
import { BaseButton } from './base-button';
import styles from './page.module.css';
 
export function Page() {
  return <BaseButton className={styles.primary} />;
}

正しい CSS 順序を維持するために、以下を推奨します。

  • CSS Modulesグローバルスタイル より優先して使用する。
  • CSS Module は単一の JS/TS ファイルにのみインポートする。
  • グローバルクラス名を使用する場合は、グローバルスタイルも同じ JS/TS ファイルにインポートする。

この変更は、ほとんどのアプリケーションに悪影響を与えるとは予想していません。しかし、アップグレード時に予期しないスタイルが表示される場合は、ドキュメントの推奨事項に従って、CSS のインポート順を確認してください。

キャッシュの改善

キャッシュは、高速で信頼性の高い Web アプリケーションを構築するための重要な部分です。ミューテーションを実行する際、ユーザーと開発者の両方が、最新の変更を反映するようにキャッシュが更新されることを期待しています。App Router の Next.js キャッシュエクスペリエンスをどのように改善できるか、検討してきました。

staleTimes (実験的)

クライアントサイドルーターキャッシュは、訪問済みおよびプリフェッチされたルートをクライアントにキャッシュすることで、高速なナビゲーションエクスペリエンスを提供するように設計されたキャッシュレイヤーです。

コミュニティからのフィードバックに基づき、クライアントサイドルーターキャッシュの無効化期間を設定できるように、実験的な staleTimes オプションを追加しました。

デフォルトでは、プリフェッチされたルート (prefetch プロップなしの <Link> コンポーネントを使用) は 30 秒間キャッシュされ、prefetch プロップが true に設定されている場合は 5 分間キャッシュされます。next.config.js でカスタム再検証時間を定義することで、これらのデフォルト値を上書きできます。

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

staleTimes は、キャッシングヒューリスティックのより多くの制御を望むユーザーの現在のエクスペリエンスを改善することを目的としていますが、完全なソリューションになることを意図していません。今後のリリースでは、全体的なキャッシングセマンティクスを改善し、より柔軟なソリューションを提供する予定です。

staleTimes の詳細については、ドキュメントをご覧ください。

並列ルートとインターセプトルート

並列ルートインターセプトルートのイテレーションを継続しており、現在はクライアントサイドルーターキャッシュとの統合を改善しています。

  • revalidatePath または revalidateTag を使用してサーバーアクションを呼び出す並列ルートおよびインターセプトルートは、キャッシュを再検証し、ユーザーの現在のビューを維持しながら、表示されているスロットを更新します。
  • 同様に、router.refresh を呼び出すと、現在のビューを維持しながら、表示されているスロットが正しく更新されるようになりました。

エラー DX の改善

バージョン 14.1 では、next dev を実行する際の、エラーメッセージとスタックトレースの可読性向上に取り組み始めました。この作業は 14.2 でも継続され、より良いエラーメッセージ、App Router および Pages Router の両方に対するオーバーレイデザインの改善、ライトモードとダークモードのサポート、そしてより明確な dev および build ログが含まれるようになりました。

例えば、React Hydration エラーは、コミュニティでよくある混乱の原因です。ハイドレーションの不一致の原因を特定するのに役立つ改善を行いました (下記参照) が、React チームと協力して、基盤となるエラーメッセージを改善し、エラーが発生したファイル名を表示するように取り組んでいます。

変更前

An example of the Next.js error overlay before version 14.2.
バージョン 14.2 より前の Next.js エラーオーバーレイの例。

変更後

An example of the Next.js error overlay after version 14.2.
バージョン 14.2 以降の Next.js エラーオーバーレイの例。

React 19

2月、React チームは React 19 のリリースを発表しました。React 19 に備えるため、最新の機能と改善を Next.js に統合する作業を進めており、これらの変更を整理するためのメジャーバージョンをリリースする予定です。

Next.js では、React canary チャンネル から利用可能だった Actions や関連フックのような新機能が、すべての React アプリケーション (クライアント専用アプリケーションを含む) で利用できるようになります。これらの機能が React エコシステムで広く採用されることを楽しみにしています。

その他の改善点

  • [ドキュメント] 動画最適化に関する新しいドキュメント (PR)。
  • [ドキュメント] instrumentation.ts に関する新しいドキュメント (PR)
  • [機能] next/image 用の新しい overrideSrc プロップ (PR)。
  • [機能] getStaticProps への新しい revalidateReason 引数 (PR)。
  • [改善] ストリーミングロジックをリファクタリングし、本番環境でのページストリーミング時間を短縮 (PR)。
  • [改善] ネストされたサーバーアクションのサポート (PR)。
  • [改善] 生成されたサイトマップでのローカリゼーションサポート (PR)。
  • [改善] dev および build ログの視覚的な改善 (PR)
  • [改善] スキュー保護が Vercel で安定しました (ドキュメント)。
  • [改善] Pages Router と useSelectedLayoutSegment の互換性を確保 (PR)。
  • [改善] 絶対 URL の解決が不要な場合に metadataBase 警告をスキップ (PR)。
  • [改善] JavaScript が無効な状態で Vercel にデプロイされた場合にサーバーアクションが送信されない問題を修正 (PR)
  • [改善] 参照元ページからナビゲートした後、または非アクティブな並列ルートセグメント内でトリガーされた場合に、サーバーアクションが見つからないというエラーを修正 (PR)
  • [改善] next/dynamic によってロードされたコンポーネントでの CSS インポートの修正 (PR)。
  • [改善] アニメーション画像に unoptimized プロップがない場合に警告を表示 (PR)。
  • [改善] images.loaderFile がデフォルト関数をエクスポートしていない場合にエラーメッセージを表示 (PR)

コミュニティ

Next.js は現在、月間アクティブ開発者数 100 万人を超えています。コミュニティのサポートと貢献に感謝いたします。会話に参加するには、GitHub DiscussionsReddit、そして Discord でご参加ください。

コントリビューター

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

@taishikato, @JesseKoldewijn, @Evavic44, @feugy, @liamlaverty, @dvoytenko, @SukkaW, @wbinnssmith, @rishabhpoddar, @better-salmon, @ziyafenn, @A7med3bdulBaset, @jasonuc, @yossydev, @Prachi-meon, @InfiniteCodeMonkeys, @ForsakenHarmony, @miketimmerman, @kwonoj, @williamli, @gnoff, @jsteele-stripe, @chungweileong94, @WITS, @sogoagain, @junioryono, @eisafaqiri, @yannbolliger, @aramikuto, @rocketman-21, @kenji-webdev, @michaelpeterswa, @Dannymx, @vpaflah, @zeevo, @chrisweb, @stefangeneralao, @tknickman, @Kikobeats, @ubinatus, @code-haseeb, @hmmChase, @byhow, @DanielRivers, @wojtekmaj, @paramoshkinandrew, @OMikkel, @theitaliandev, @oliviertassinari, @Ishaan2053, @Sandeep-Mani, @alyahmedaly, @Lezzio, @devjiwonchoi, @juliusmarminge, @szmazhr, @eddiejaoude, @itz-Me-Pj, @AndersDJohnson, @gentamura, @tills13, @dijonmusters, @SaiGanesh21, @vordgi, @ryota-murakami, @tszhong0411, @officialrajdeepsingh, @alexpuertasr, @AkifumiSato, @Jonas-PFX, @icyJoseph, @florian-lp, @pbzona, @erfanium, @remcohaszing, @bernardobelchior, @willashe, @kevinmitch14, @smakosh, @mnjongerius, @asobirov, @theoholl, @suu3, @ArianHamdi, @adrianha, @Sina-Abf, @kuzeykose, @meenie, @nphmuller, @javivelasco, @belgattitude, @Svetoslav99, @johnslemmer, @colbyfayock, @mehranmf31, @m-nakamura145, @ryo8000, @aryaemami59, @bestlyg, @jinsoul75, @petrovmiroslav, @nattui, @zhuyedev, @dongwonnn, @nhducit, @flotwig, @Schmavery, @abhinaypandey02, @rvetere, @coffeecupjapan, @cjimmy, @Soheiljafarnejad, @jantimon, @zengspr, @wesbos, @neomad1337, @MaxLeiter, and @devr77 に多大な感謝を申し上げます!