2020年1月6日月曜日
Next.js 9.1.7
投稿者Next.js 9 は6ヶ月前にリリースされ、続いてNext.js 9.1が3ヶ月前にリリースされました。
これら2つのリリースにより、Next.jsに非常に強力な新機能が追加されましたが、クライアントのベースラインランタイムサイズは増加していません。
それ以来、私たちはフレームワーク全体の改良と改善に注力してきました。具体的には、9.1.1、9.1.2、9.1.3、9.1.4、9.1.5、9.1.6、そして9.1.7です。
これらのリリースで何が改善されたか、詳しく見ていきましょう!
- 3%~8%以上のクライアントサイドJavaScriptサイズの削減: アプリケーションの出力がさらに最適化され、Hello Worldアプリケーションで7.5kBの削減を実現しました。より複雑なアプリケーションでは、8%以上の削減が見込まれます。
- 再設計されたプロダクションビルドCLI出力: プロダクションビルドの出力が、Gzip圧縮されたファイルサイズをより分かりやすい形式で表示するようになりました。
- 新しい組み込みポリフィル: fetch()、URL、および Object.assign: レガシーブラウザでも互換性の問題を心配することなく、
fetch()
API、URL
、およびObject.assign
をアプリケーションで利用できるようになりました。 - 最適化されたページ読み込み: 改善されたFCPとTTI: Google Chromeチームと緊密に連携し、ページ読み込みパフォーマンスを最大化しました。これにより、エンドユーザーエクスペリエンスが大幅に向上します。
- 最新のJavaScript機能のサポート: Optional Chaining、Nullish Coalescing、その他安定したES2020機能を含む、常に最新のJavaScript機能を使用できるよう尽力しています。
next export
アプリケーションのゼロコンフィグデプロイメントサポート:next export
を利用したアプリケーションが、Vercelへゼロコンフィグでデプロイできるようになりました。- React Strict Modeへの準拠とオプトイン: Next.jsのすべてのクライアントサイドランタイムがReactのStrict Modeに対応しました。アプリケーション全体でこのモードを有効にするための設定オプションも追加されています。
- React Nightlyビルドに対する自動テスト: Next.jsはReactの次期チャネルに対して自動的にテストされるようになり、将来のリリースとの互換性が保証されます。
これらの利点はすべて破壊的な変更を含まず、完全に後方互換性があります。更新するには、以下を実行するだけです。
npm i next@latest react@latest react-dom@latest
3%~8%以上のクライアントサイドJavaScriptサイズの削減
Google Chromeチームとの協力により、すべてのNext.jsアプリケーションは**7.5kB以上**のサイズ削減の恩恵を受けます。
基本的なアプリケーションでは3〜4%のアプリケーションサイズ削減が見られ、より高度なアプリケーションでは6〜8%(またはそれ以上)の削減が見込まれます!
9.0.x | 9.1.x | 差分 | |
---|---|---|---|
基本アプリケーション | 68.9kB | 66.1kB | 4.1% の削減 |
これらの削減は、url
パッケージのクライアントサイドバージョンを置き換え、URL APIの上に構築されたものを使用していることにも一部起因しています。
さらに、頻繁に使用されるパッケージ向けに組み込みの小さなポリフィルを提供することで、さらなるサイズ削減が達成されました。これらのポリフィルについてはこちらで詳しく読むことができます。
最後に、JSX出力も最適化され、アプリケーション内のJSXの量に直接比例して削減効果が得られます。
再設計されたプロダクションビルドCLI出力
CLIのプロダクションビルド出力が、より明確になるように再設計されました。Next.jsはハイブリッドアプリケーションフレームワークであるため、各ページは異なる特性を持つ場合があります。
新しい出力では、各ページが以下のいずれかに分類されます。
- サーバーサイドレンダリング (Server): ページは実行時にサーバーサイドでレンダリングされます。つまり、
getInitialProps
またはgetServerProps
(提案中) を使用します。 - 自動静的最適化 (Static): ページはビルド時に静的HTMLとしてレンダリングされ、静的ファイルとして提供されます(初期プロパティは使用しません)。
- 計算されたデータを使用した静的生成 (SSG): ページはビルド時に静的HTML/JSONとして生成され、静的ファイルとして提供されます(
getStaticProps
(提案中) を使用)。
さらに、新しい出力では各ページのGzip圧縮サイズが表示されます。これらのサイズには、すべてのページで共有されるファイルは含まれていません(別途表示されます)。
各ページのサイズは、認識されるユーザーエクスペリエンスに応じて色分けされます。
- 130kB未満: 緑 — ほとんどのネットワークおよびデバイス条件下で、アプリケーションは高いパフォーマンスを発揮します。
- 130kBから170kBの間: 黄 — グローバルベースラインのデバイスとネットワーク条件で、アプリケーションの読み込み時間が5〜6秒に近づいています。
- 170kB以上: 赤 — 同じ条件で、アプリケーションの読み込みに6秒以上かかる可能性が高いです。

新しいビルド出力についてのご意見をお待ちしております。
近い将来、Next.jsには、ページが特定のサイズ範囲内に収まるようにするためのサイズ予算機能も追加される予定です。
新しい組み込みポリフィル: fetch()、URL、および Object.assign
多くのユーザーのアプリケーションと私たちの例を調査した結果、ほとんどが同様のポリフィルのセットで提供されていることがわかりました。場合によっては、同じ機能に対して重複したポリフィルが含まれているアプリケーションもありました。
この問題を解決するため、私たちはGoogle Chromeチームと協力し、観察された最も一般的な3つのAPI用のポリフィルを組み込みました。
差分ローディングを使用することで、これらのポリフィルは世界中で**Webトラフィックの83%で読み込まれません**。これは、ほとんどのユーザーがこれらのポリフィルに関連するバイトをダウンロードしないことを意味します。必要な場合にのみダウンロードされます。
さらに、今回組み込まれた既知のポリフィルは、プロダクションビルドから完全に削除されます。これにより、これらのAPIのいずれかのポリフィルを誤ってインポートする依存関係に対して、余分なコストを支払う必要がなくなります。
組み込みAPIとその結果として不要になるポリフィルのリストは以下の通りです。
- fetch() — 置換対象:
whatwg-fetch
およびunfetch
。 - URL — 置換対象:
url
パッケージ (Node.js API)。 - Object.assign() — 置換対象:
object-assign
、object.assign
、およびcore-js/object/assign
。
サーバーサイドでfetch()
を使用する場合は、引き続きisomorphic-fetch
またはisomorphic-unfetch
をインポートする必要があります。
この変更は完全に破壊的なものではなく、すべてのポリフィルは利用可能な最も仕様に準拠したバージョンで作成されています。その結果、モダンブラウザのプロダクションバンドルから**最大18kBのJavaScriptが削減**されます。
最適化されたページ読み込み: 改善されたFCPとTTI
Next.jsはプリロードの実装を最適化し、FCPと全体のTTIを削減しました。
ブラウザのバグを回避することで、CSS(使用されている場合)がJavaScriptよりも正しく優先されるようになりました。これにより、First Contentful Paintが高速化され、エンドユーザーにとって視覚的に完成されたウェブサイトの表示が大幅に高速化されます。
さらに、ページプリフェッチを最適化し、優先度の低いネットワークリクエストを使用するようにしました。
また、これらのリクエストはブラウザのアイドル時にのみ発生するため、インタラクティブになるまでの時間が短縮されます。これは、ブラウザが楽観的なプリフェッチよりもアプリケーションのインタラクティブ性を優先するためです。

最新のJavaScript機能のサポート
Next.jsは、最新のJavaScript機能を使用できる高度に最適化されたコンパイルパイプラインを備えています。導入された最新の最適化は、アプリケーションサイズの3~8%削減に直接貢献しました。
これらのJavaScript機能は、ブラウザの互換性を心配することなく利用できます。私たちは自動的にコードをすべてのブラウザ(サポート終了バージョンを除く)に対応するようにコンパイルします。これには、async/await (ES2017)、Object Rest/Spread Properties (ES2018)、動的 import()
(ES2020)など、ES6+の機能が含まれます。
このリリースでは、Optional Chaining (Stage 4) と Nullish Coalescing (Stage 4) のサポートを発表できることを嬉しく思います。
function Page(props) {
return (
<p>{props?.deeply?.nested?.value}</p>
/* ⬆ If deeply.nested.value is not available it won't render */
);
}
export default Page;
オプショナルチェイニング演算子 (
?.
)
function Page(props) {
return (
<p>{props.something ?? 'Default value'}</p>
/* ⬆ results in "Default value" */
);
}
export default Page;
Nullish coalescing演算子 (
??
)
将来的には、自動的なモジュール/ノーモジュールビルドを介して、さらに最適化されたバンドルを出力する予定です。
next export
アプリケーションのゼロコンフィグデプロイメントサポート
Next.jsのnext export
コマンドは、Vercelのゼロコンフィギュレーションとすぐに連携できるようになりました。この変更以前は、next export
を利用するユーザーはカスタムのnow.json
を作成する必要がありました。
VercelでNext.jsのエクスポートモードを活用するには、package.json
に以下のbuild
スクリプトを用意するだけで簡単にできます。
{
"scripts": {
"build": "next build && next export"
}
}
その後、たった1つのコマンドでNext.jsアプリケーションをVercelにデプロイできます。Vercelをまだインストールしていない場合は、Vercel CLIをインストールすることで可能です。
now
React Strict Modeへの準拠とオプトイン
Next.jsのランタイム全体がStrict Modeに準拠しました。これには、Next.jsのヘッドマネージャー(<Head>
)、next/dynamic
、その他のコア機能への更新が含まれます。これは、ランタイムがフックを利用したり、非推奨のライフサイクルを廃止したり、Reactの新しいContext APIを使用していることを意味します。
また、アプリケーションでStrict Modeを有効にするための便利なオプトインオプションも追加しました。
それには、next.config.js
に以下のオプションを設定してください。
module.exports = {
reactStrictMode: true,
};
ご自身またはチームがアプリケーション全体でStrict Modeを使用する準備ができていない場合でも問題ありません!<React.StrictMode>
を使用してページごとに段階的に移行することができます。
Strict Modeは**必須ではありません**が、将来的に多くの最適化を可能にします。このため、早めに検討することをお勧めします!
React Nightlyビルドに対する自動テスト
React Core Teamとの密接な協力により、Next.jsは現在、Reactの次期チャネルに対して12時間ごとにテストされています。
これらのテストは、Reactの将来のリリースに備え、互換性を確保するのに役立ちます。互換性はNext.jsが非常に重要視していることであり、Next.jsの長期的なAPI安定性にコミットしています。
このプロセスは、Reactエコシステム内の他のプロジェクトもこれに倣うことを期待し、React Core Teamによって文書化されています。
コミュニティ
すべてのNext.jsアプリケーションにおいてサイズとパフォーマンスを向上させる、今後の変更に期待しています。
さらに、Next.jsコミュニティは拡大を続けています。
- これまでに865を超える独立した貢献者がいました。
- GitHubでは、このプロジェクトは43,700回以上スターを獲得しています。
- The examplesディレクトリには220を超えるexampleがあります。
Next.jsコミュニティには現在、13,600を超えるメンバーがいます。 参加する!
コミュニティの皆様、そしてこのリリースを形作る上でご協力いただいたすべての外部からのフィードバックと貢献に感謝いたします。