【全文和訳】Next.js 9.2

https://cdn-ak.f.st-hatena.com/images/fotolife/c/commmune/20200127/20200127171249.jpg

(以下は2020年1月15日に公開された Next.js 9.2 の日本語和訳です。 以下原文 )

https://nextjs.org/blog/next-9-2

 

心躍る、Next.js 9.2の発表です:

  • Built-In CSS Support for Global Stylesheets: アプリケーションは .css ファイルをグローバルスタイルシートとしてインポートすることができます。

  • Built-In CSS Module Support for Component-Level Styles: .module.css を活用し、ローカルで見つかった CSS はアプリケーションのどこにでもインポートし、使用可能になります。

  • Improved Code-Splitting Strategy: Google ChromeチームがNext.js' code-splitting strategyを磨き、クライアント側でのバンドルを縮小することに成功しました。 また、HTTP/2 の利用率を上げることによって、HTTP/1.1のパフォーマンスを損なわず、ページのロード時間を改善しました。 

  • Catch-All Dynamic Routes: Next.js' Dynamic Routes は、catch-all routesへの対応により、様々なユースケースで活用できるようになりました。例:CMS-powered websites.

これらすべての恩恵は、過去のリリースに対応しています。アップデートを行うためには、以下のコードを実行するだけです:

$npm i next@latest react@latest react-dom@latest

Next.js 5では、next.csの動作を拡張するnext-cssと呼ばれるカスタムプラグインを介してCSSをインポートするサポートが導入されました。
しかし、その時から、Next.jsの企業とユーザーより、結局アプリケーションにnext-cssを追加しているという一貫としたフィードバックを得てきました。
さらに、CSSのインポート時に、next-cssにはいくつかの制約が欠如していました。 例えば、プロジェクトの個々のファイルにおいてCSSファイルのインポートが可能でしたが、このインポートされたCSSファイルはアプリケーション全体で共有されていました。
ユーザーの開発体験を改善し、これらの矛盾を解決するために、私たちはデフォルトでNext.jsにCSSインポートサポートを実装する作業をしていました。
この度、Next.jsでスタイルシートをアプリケーションにインポートするためのネイティブサポートが追加されたことをお知らせします。
アプリケーションでCSSインポートの使用を開始するには、pages/_app.js.にCSSファイルをインポートします。
例えば、プロジェクトのルートにある、styles.cssという名前の次のスタイルシートをご覧ください:

f:id:commmune:20200123190903j:plain

pages/_app.js ファイル を作成してください(まだなければ)。次に、styles.css ファイルをインポートしてください: 

f:id:commmune:20200123192640j:plain

スタイルシートは本質的にグローバルであるため、Custom <App> componentにインポートする必要があります。 これは、グローバルスタイルのクラス名と順序の競合を避けるために必要です。
開発では、この方法でスタイルシートを表現することにより、スタイルを編集すると、ページ上でスタイルが自動的に更新されます。
プロダクション
では、すべてのCSSファイルが単一の、縮小された.cssファイルに自動的に連結されます。 このCSSファイルは<link>タグを介してロードされ、Next.jsが生成するデフォルトのHTMLマークアップに自動的に挿入されます。
この新しい機能は完全に後方互換性があります。@zeit/next-cssまたは他のCSS関連プラグインを使用されている場合、コンフリクトを避けるために機能は無効になります。
現在、@zeit/next-cssを使用されている場合、next.config.jsおよびpackage.jsonからプラグインを削除し、アップグレード時に組み込みCSSサポートに移行することをお勧めします。

Next.js 5で利用可能であった、next-cssを使ったサポートとは異なり、グローバルCSSとCSSモジュールが共存できるようになりました。以前、next-cssは、アプリケーションのすべての.cssファイルがグローバル又はローカルとして扱われることはあっても、両方ということはありませんでした。
CSSモジュールは、ユニークなクラス名を自動的に生成することでCSSを見つけ出します。 これにより、衝突を心配することなく、異なるファイルで同じCSSクラス名の使用が可能です。
これにより、CSSモジュールはコンポーネントレベルのCSSを含める理想的な形式になります。 CSSモジュールファイルは、アプリケーションのどこにでもインポートできます。
components/フォルダー内の再利用可能なButtonコンポーネントを例とします。
最初に、次の内容でcomponents/Button.module.cssを作成します:

f:id:commmune:20200123194906j:plain

次に、以下のCSSファイルをインポートして、components/Button.jsを作成します。

f:id:commmune:20200123194912j:plain

 

CSSモジュールはオプション機能であり、拡張子が.module.cssのファイルでのみ有効になります。 通常の <link>スタイルシートとグローバルCSSファイルは引き続きサポートされます。
プロダクションでは、すべてのCSSモジュールファイルが自動的に連結され、多くの縮小およびコード分割された.cssファイルになります。 これらの.cssファイルはアプリケーションのhot execution pathを表し、アプリケーションがペイントするために、ページ毎に最小限のCSSがロードされるようにします。
上記のように、この新しい機能は完全に後方互換性があります。 @zeit/next-cssまたは他のCSS関連プラグインを使用している場合、コンフリクトを避けるために機能は無効になります。

現在、@zeit/next-cssを使用されている場合、next.config.jsおよびpackage.jsonからプラグインを削除し、組み込みCSSサポートに移行することをお勧めします。

9.2より前のバージョンのNext.jsには、ページをロードしてインタラクティブにするために必要なJavaScriptバンドルの固定されたセットがありました。

  • The page's JavaScript file
  • A file with common JavaScript
  • Next.js client-side runtime bundle
  • Webpack client-side runtime bundle
  • Dynamic imports (added through next/dynamic, when used)

これらのバンドルはReactを起動する上で、互いに依存しているため、ページをインタラクティブにするには、これらすべてをロードする必要があります。
これらのバンドルはすべて、アプリケーションがインタラクティブになるために必要であるため、可能な限り最適化することが重要です。 実際、これはアプリケーションの他の部分からコードを過剰ダウンロードしないことを意味します。
このため、Next.jsはページ間で共通のJavaScriptを保持するcommonsバンドルを使用しました。 commonsを生成するための古いバンドル分割戦略の計算は、使用率のヒューリスティックでした。 モジュールがすべてのページの50%以上で使用された場合、共通モジュールとしてマークされます。 それ以外の場合は、ページのJavaScriptファイルにバンドルされていました。
しかし、アプリケーションはさまざまな種類のページで構成できます。 たとえば、マーケティングページ、ブログ、ダッシュボードなど。 他のページタイプと比較して多数のマーケティングページがある場合、コモンズの計算により、マーケティングページに重点を置いた最適化が行われます。
私たちの目標は、1つのアプリケーションですべてのページタイプを最適化することです。
新たなヒューリスティクスでは、以下のように最適化されます:

  • A minimal chunk for each page.
  • A framework chunk containing React, ReactDOM, React's Scheduler, etc.
  • Library chunks for any node_module dependency over 160kb (pre-minify/gzip)
  • A commons chunk for code used across all pages.
  • As many shared chunks (used by 2 or more pages) as possible, optimizing for overall application size and initial load speed.
  • Next.js' client-side runtime.
  • Webpack runtime.

現実において、これが何を意味するのか見てみましょう。
この技術が早期に採用された業界パートナーのBarnebys®では、アプリケーション全体のサイズが23%減少しました。 さらに、最大のJSバンドルは30%削減されました(605kBは425kBに削減)-コードの変更は不要です。
別の業界パートナーであるSumUp®では、最大のJSバンドルが395kBから122kBに削減され、コードを変更することなく70%減少しました。

f:id:commmune:20200123204220j:plain

新しいチャンク動作により、全体のサイズと初期ロードサイズが削減されるだけでなく、クライアント側の連続したナビゲーションも削減されます。 Barnebys®では、6回のページナビゲーション後に読み込まれるJavaScriptの量が87%削減されました。

f:id:commmune:20200123204331j:plain

この新しい動作は完全に後方互換性があります。 このパフォーマンスの向上を活用するには、Next.jsの最新バージョンにアップグレードするだけです。

 

Next.js 9のリリースでは、カスタムサーバーなしにNext.jsのdynamic segmentsを簡素化する目的で、dynamic route segmentsを導入しました。 この機能は、Next.jsユーザーに大々的に採用されています。
しかし、dynamic route segments機能ではカバーされない場合がまだいくつかありました。
これらのケースの1つは、catch-all routesです。 たとえば、/post/**などのワイルドカードをページとしてルーティングします。 これは、CMSなどのコンテンツソースによって定義されるネストされた構造がある場合に特に便利です。
[...name]構文を使用して、catch-all dynamic routeを作成できるようになりました。
たとえば、pages/post/[...slug].jsは、/post/a, /post/a/b, /post/a/b/cなどに一致します。
slug は、個々のパス部分の配列としてルータークエリオブジェクトで提供されます。 したがって、/post/foo/barの場合、クエリオブジェクトは{ slug: ['foo', 'bar'] }になります。

Next.jsの採用が引き続き拡大していることに、我々はとても喜んでいます:

  • 880 人以上の人が協力してくれました
  • GitHubでは、プロジェクトに 44,000回スターが付きました
  • examples directory には 220 以上の事例が入稿されました

 spectrum.chat/next-js におけるNext.jsのコミュニティには、現在 13,800 以上のメンバーが参加しています。Join us!

このリリースにあたり、私たちのコミュニティ、外部からのフィードバック及び力添えに感謝します。