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

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 で動作します。
  • Rust で記述された高速 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

ページ間を移動する際にスタイルが競合しないように、CSS をチャンク化することにより、本番環境の Next.js ビルド中に 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 モジュールグローバルスタイルより優先して使用する。
  • CSS モジュールを単一の 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のハイドレーションエラーは、コミュニティでよく混乱を招く原因となっています。ハイドレーションのミスマッチの原因を特定するのに役立つ改善を行いましたが(下記参照)、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に統合する作業を進めており、これらの変更を調整するためにメジャーバージョンをリリースする予定です。

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

その他の改善点

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

コミュニティ

Next.js は現在、月間アクティブ開発者数が100万人を超えています。コミュニティのサポートと貢献に感謝しています。 GitHub Discussions、 Reddit、そして 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, そして @devr77 の皆様、ご協力いただきありがとうございます!