2024年1月18日 木曜日
Next.js 14.1
投稿者Next.js 14.1 には、開発者エクスペリエンスの改善が含まれています。具体的には以下の通りです。
- セルフホスティングの改善: 新しいドキュメントとカスタムキャッシュハンドラー
- Turbopack の改善:
next dev --turboで 5,600 件のテストに合格 - DX の改善: エラーメッセージの改善、
pushStateおよびreplaceStateのサポート - 並列ルーティングとインターセプトルーティング: フィードバックに基づいた 20 件のバグ修正
next/imageの改善:<picture>、アートディレクション、ダークモードのサポート
今日アップグレードするか、以下から始めましょう。
npx create-next-app@latestセルフホスティングの改善
Node.js サーバー、Docker コンテナ、または静的エクスポートを使用して Next.js をセルフホストする方法についてのフィードバックを受け、明確化に努めてきました。セルフホスティングのドキュメントを全面的に見直しました。
Next.js 14.1 では、App Router 向けのインクリメンタル静的再生成 (ISR) およびより詳細なデータキャッシュのカスタムキャッシュハンドラーの提供を安定化しました。
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
};Kubernetes のようなコンテナオーケストレーションプラットフォームを使用する場合、各 Pod がキャッシュのコピーを持つため、セルフホスティング時にこの構成を使用することが重要です。カスタムキャッシュハンドラーを使用すると、Next.js アプリケーションをホストするすべての Pod 間で一貫性を確保できます。
例えば、キャッシュされた値を Redis や Memcached など、どこにでも保存できます。@neshca の Redis キャッシュハンドラーアダプター とその例に感謝します。
Turbopack の改善
ローカルでの Next.js 開発の信頼性とパフォーマンスに引き続き注力しています。
- 信頼性: Turbopack が Next.js 開発テストスイート全体に合格し、Vercel のアプリケーションでも内部使用 (dogfooding) されています。
- パフォーマンス: Turbopack の初回コンパイル時間と Fast Refresh の時間を改善
- メモリ使用量: Turbopack のメモリ使用量を改善
next dev --turbo は、今後のリリースで安定化する予定ですが、引き続きオプトインとなります。
信頼性
Turbopack は、Next.js 開発テストスイート全体に合格しました (94%)。これは前回のアップデートから 600 件増加しています。進捗状況は areweturboyet.com で確認できます。
Vercel のすべての Next.js アプリケーション (vercel.com や v0.app を含む) で next dev --turbo の内部使用 (dogfooding) を継続しています。これらのアプリケーションに取り組むすべてのエンジニアが毎日 Turbopack を使用しています。
Turbopack を使用する非常に大規模な Next.js アプリケーションで、いくつかの問題を発見し修正しました。これらの修正のため、既存の Next.js 開発テストスイートに新しいテストを追加しました。
パフォーマンス
vercel.com という大規模な Next.js アプリケーションで、以下の改善が見られました。
- ローカルサーバー起動時間が最大 76.7% 高速化
- Fast Refresh によるコード更新が最大 96.3% 高速化
- 初回ルートコンパイル時間がキャッシュなしで最大 45.8% 高速化 (Turbopack はまだディスクキャッシュを備えていません)
v0.app では、React Client Component の検出とバンドリング方法を最適化できる機会を見つけました。これにより、初回コンパイル時間が最大 61.5% 短縮されました。このパフォーマンス向上は、vercel.com でも観測されました。
今後の改善
Turbopack は現在インメモリキャッシュを備えており、Fast Refresh のインクリメンタルコンパイル時間を改善します。
しかし、現在のところキャッシュは Next.js 開発サーバーを再起動しても保持されません。Turbopack のパフォーマンスにおける次の大きなステップはディスクキャッシュであり、これにより開発サーバーの再起動時にキャッシュを保持できるようになります。
開発者エクスペリエンスの改善
エラーメッセージの改善と Fast Refresh
ローカル開発エクスペリエンスにおいて、明確なエラーメッセージがいかに重要であるかは承知しています。next dev を実行した際に表示されるスタックトレースとエラーメッセージの質を向上させるため、数多くの修正を行いました。
- 以前は
webpack-internalのようなバンドラーエラーが表示されていたエラーでも、エラーのソースコードと影響を受けるファイルが正しく表示されるようになりました。 - クライアントコンポーネントでエラーが発生した後、エディタでエラーを修正しても Fast Refresh でエラー画面がクリアされず、ハードリロードが必要でした。これらのインスタンスのいくつかを修正しました。例えば、クライアントコンポーネントから
metadataをエクスポートしようとした場合などです。
例えば、これは以前のエラーメッセージでした。

Next.js 14.1 では、これを以下のように改善しました。

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 経由で有効にできます。
module.exports = {
logging: {
fetches: {
fullUrl: true,
},
},
};next/image での <picture> およびアートディレクションのサポート
Next.js Image コンポーネントは、<Image> を直接使用する必要がない getImageProps() (安定版) を通じて、より高度なユースケースをサポートするようになりました。これには以下が含まれます。
background-imageまたはimage-setとの連携- キャンバスの
context.drawImage()またはnew Image()との連携 <picture>メディアクエリを使用して、アートディレクション またはライト/ダークモードの画像を実装
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 のパフォーマンスと信頼性の向上に注力してきました。現在、並列ルーティング および インターセプトルーティング に多くの改善を加えました。特に、キャッチオールルートと Server Actions のサポートを追加しました。
- 並列ルーティングを使用すると、同じレイアウト内で 1 つ以上のページを同時にまたは条件付きでレンダリングできます。ダッシュボードやソーシャルサイトのフィードなど、アプリの高度に動的なセクションでは、複雑なルーティングパターンを実装するために並列ルーティングを使用できます。
- インターセプトルーティングを使用すると、現在のレイアウト内でアプリケーションの別の部分からルートを読み込むことができます。例えば、フィード内の写真をクリックすると、フィードをオーバーレイしてモーダルで写真を表示できます。この場合、Next.js は
/photo/123ルートをインターセプトし、URL をマスクして/feedの上にオーバーレイします。
並列ルーティングとインターセプトルーティングについては こちら、または例をこちらでご覧いただけます (例を表示)。
その他の改善点
14.0 以降、コミュニティから多くのアップボートがあったバグをいくつか修正しました。
最近、キャッシュ に関する動画や、App Router に関するよくある間違い についての動画も公開しました。これらが参考になるかもしれません。
- [ドキュメント] リダイレクト に関する新しいドキュメント
- [ドキュメント] テスト に関する新しいドキュメント
- [ドキュメント] 本番環境チェックリスト に関する新しいドキュメント
- [機能]
next/third-partiesに<GoogleAnalytics />コンポーネントを追加 (ドキュメント) - [改善]
create-next-appがより小さく、インストールが高速になりました (PR) - [改善] ネストされたルートでエラーが発生しても、
global-errorでキャッチできます (PR) - [改善] サーバーアクションで使用される
redirectは、basePathを尊重するようになりました (PR) - [改善] App Router での
next/scriptおよびbeforeInteractiveの使用を修正 (PR) - [改善]
@aws-sdkおよびlodashを自動的にトランスパイルして、ルート起動を高速化 (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)
- [改善]
SuspenseなしでuseSearchParamsを誤って使用した場合、ビルド時にエラーが表示されるようになります (PR)
コントリビューター
Next.js は、3,000 人以上の個々の開発者、Google や Meta といった業界パートナー、そして Vercel のコアチームの共同作業の成果です。コミュニティにご参加ください。 GitHub Discussions、Reddit、そして Discord で。
このリリースは、以下の方々によってもたらされました。
- Next.js チーム: Andrew, Balazs, Jiachi, Jimmy, JJ, Josh, Sebastian, Shu, Steven, Tim, Wyatt, and Zack.
- Turbopack チーム: Donny, Leah, Maia, OJ, Tobias, and Will.
- Next.js ドキュメント: Delba, Steph, Michael, and Lee.
そして、@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 の貢献。