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です。
これらのリリースで何が改善されたのか見ていきましょう!
- クライアントサイドJavaScriptサイズが3%~8%以上縮小: アプリケーションの出力をさらに最適化し、「Hello World」アプリケーションから7.5kB削減しました。より複雑なアプリケーションでは、最大8%以上の削減効果が見られます。
- 本番ビルドCLI出力の再設計: 本番ビルド出力には、gzip圧縮後のファイルサイズが、より分かりやすい形式で表示されるようになりました。
- 新しい組み込みポリフィル: fetch()、URL、およびObject.assign: アプリケーションは、互換性の問題なく、レガシーブラウザでも`fetch()` API、`URL`、`Object.assign`を利用できるようになりました。
- ページ読み込みの最適化: FCPとTTIの改善: Google Chromeチームと緊密に協力して、ページ読み込みのパフォーマンスを最大化しました。これにより、エンドユーザーエクスペリエンスが大幅に向上します。
- 最新のJavaScript機能のサポート: オプショナルチェイニング、ナルリッシュ・コアレシング、その他の安定したES2020機能など、常に最新のJavaScript機能を使用できるように取り組んでいます。
- `next export`アプリケーションのゼロコンフィグデプロイメントサポート: `next export`対応アプリケーションは、Vercelにゼロコンフィグでデプロイできるようになりました。
- React Strict Modeの準拠とオプトイン: Next.jsのクライアントサイドランタイムはすべて、ReactのStrict Modeと互換性があります。アプリケーション全体でこのモードを有効にするための設定オプションも追加されました。
- Nightly Reactビルドに対する自動テスト: Next.jsはReactのnextチャンネルに対して自動的にテストされており、将来のリリースとの互換性が確保されています。
これらの利点はすべて、破壊的ではなく、完全に後方互換性があります。アップデートするには、次のコマンドを実行するだけです。
npm i next@latest react@latest react-dom@latest
クライアントサイドJavaScriptサイズを3%~8%以上削減
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はハイブリッドアプリケーションフレームワークであるため、各ページには異なる特性があります。
新しい出力では、各ページを次のいずれかの種類に分類します。
- サーバーサイドレンダリング(サーバー):ページは実行時にサーバーサイドでレンダリングされます。つまり、
getInitialProps
またはgetServerProps
(提案)を使用します。 - 自動静的最適化(静的):ページはビルド時に静的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が高速化され、エンドユーザーにとって視覚的に完成したWebサイトが大幅に高速になります。
さらに、ページプリフェッチを最適化して、低優先度のネットワークリクエストを使用するようにしました。
さらに、これらのリクエストはブラウザのアイドル時間中のみ行われるため、対話型になるまでの時間が短縮されます。これは、ブラウザが楽観的なプリフェッチよりもアプリケーションの対話性を優先するためです。


最新のJavaScript機能のサポート
Next.jsには、最新のJavaScript機能を使用できる高度で最適化されたコンパイルパイプラインがあります。最近導入された最適化により、アプリケーションサイズが3~8%削減されました。
これらのJavaScript機能は、ブラウザの互換性を気にすることなく利用できます。コードは、(サポート終了バージョンを除く)すべてのブラウザをサポートするように自動的にコンパイルされるからです。これには、非同期/await (ES2017)、オブジェクトのレスト/スプレッドプロパティ (ES2018)、動的import()
(ES2020)など、多くのES6+機能が含まれています!
今回のリリースでは、オプショナルチェイニング (Stage 4)とNullish合体演算子 (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合体演算子 (
??
)
将来は、自動module/nomoduleビルドにより、さらに最適化されたバンドルを出力する予定です。
next export
アプリケーションのゼロコンフィグデプロイメントサポート
Next.jsのnext export
コマンドは、Vercelのゼロコンフィグレーションとすぐに連携するようになりました。この変更前は、next export
を利用するユーザーは、カスタムnow.json
を作成する必要がありました。
VercelでNext.jsのエクスポートモードを活用するには、package.json
に次のbuild
スクリプトを含めるだけで済みます。
{
"scripts": {
"build": "next build && next export"
}
}
その後、たった一つのコマンドでVercelにNext.jsアプリケーションをデプロイできます。Vercelをまだインストールしていない場合は、Vercel CLIをインストールすることで行えます。
now
React ストリクトモードへの準拠とオプトイン
Next.jsランタイム全体がストリクトモードに準拠するようになりました。これには、Next.jsのヘッドマネージャー(<Head>
)、next/dynamic
、その他の主要な機能のアップデートが含まれています。つまり、ランタイムはフックを利用するか、非推奨のライフサイクルを削除し、Reactの新しいコンテキストAPIを使用するようになりました。
また、アプリケーションでストリクトモードを有効にするための便利なオプトインオプションも追加しました。
これを行うには、next.config.js
で次のオプションを設定します。
module.exports = {
reactStrictMode: true,
};
あなたまたはあなたのチームがアプリケーション全体でストリクトモードを使用する準備ができていない場合でも問題ありません!<React.StrictMode>
を使用して、ページ単位で段階的に移行できます。
必須ではありませんが、ストリクトモードを使用することで、将来多くの最適化が可能になります。そのため、早いうちに検討することをお勧めします!
Nightly Reactビルドに対する自動テスト
Reactコアチームと緊密に連携して、現在テストを12時間ごとにReactのネクストチャンネルに対して実行しています。
これらのテストは、Reactの今後のリリースに対応し、互換性を確保するのに役立ちます。Next.jsは互換性を非常に重視しており、Next.jsの長期的なAPIの安定性を約束しています。
このプロセスは、Reactエコシステム内の他のプロジェクトも同様のことを行うことを期待して、Reactコアチームによって文書化されています。
コミュニティ
すべてのNext.jsアプリケーションのサイズとパフォーマンスを向上させる今後の変更に興奮しています。
さらに、Next.jsコミュニティは拡大を続けています。
- 865名以上の独立した貢献者がいます。
- GitHubでは、プロジェクトは43,700回以上スターされています。
- examplesディレクトリには、220以上の例があります。
Next.jsコミュニティには現在、13,600名以上のメンバーがいます。参加しましょう!
コミュニティの皆様、そしてこのリリースを形作るのに役立った外部からのフィードバックと貢献に感謝いたします。