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

2020年1月6日月曜日

Next.js 9.1.7

投稿者

Next.js 9 は6ヶ月前にリリースされ、その後Next.js 9.1が3ヶ月前にリリースされました。

これらの2つのリリースでは、Next.jsに非常に強力な新機能が追加されましたが、基本的なクライアントランタイムのサイズは増加していません。

それ以来、フレームワーク全体の改良と改善に重点的に取り組んできました。 9.1.19.1.29.1.39.1.49.1.59.1.6、そして9.1.7です。

これらのリリースで何が改善されたのか見ていきましょう!

これらの利点はすべて、破壊的ではなく、完全に後方互換性があります。アップデートするには、次のコマンドを実行するだけです。

ターミナル
npm i next@latest react@latest react-dom@latest

クライアントサイドJavaScriptサイズを3%~8%以上削減

Google Chromeチームとの共同作業により、すべてのNext.jsアプリケーションで7.5kB以上のサイズ削減を実現します。

基本的なアプリケーションではアプリケーションサイズが3~4%削減され、より高度なアプリケーションでは6~8%以上削減される可能性があります!

9.0.x9.1.x差分
基本アプリケーション68.9kB66.1kB4.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秒を超える可能性があります。
The New Next.js Production CLI Output
新しいNext.js本番CLI出力

新しいビルド出力に関するご意見をお聞かせいただければ幸いです。

近い将来、Next.jsには、ページが特定のサイズ範囲内にあることを確認するのに役立つサイズ予算も追加される予定です。

新しい組み込みポリフィル: fetch()、URL、およびObject.assign

多くのユーザーのアプリケーションと弊社の例を調べた結果、ほとんどのアプリケーションが同様のポリフィルセットで提供されていることがわかりました。場合によっては、アプリケーションに同じ機能のポリフィルが重複して含まれていることもありました。

これを解決するために、Google Chromeチームと協力して、最も一般的な3つのAPIのポリフィルを組み込みました。

差分ローディングを使用することで、これらのポリフィルはグローバルなWebトラフィックの83%にはロードされません。これは、ほとんどのユーザーがこれらのポリフィルに関連付けられたバイトをダウンロードしないことを意味します。必要になった場合にのみダウンロードされます。

さらに、現在組み込まれている既知のポリフィルは、本番ビルドから完全に削除されます。つまり、これらのAPIのポリフィルを意図せずインポートする依存関係のために、コストを支払う必要がなくなります。

組み込みAPIと、それらが非推奨とするポリフィルのリストを以下に示します。

サーバーでfetch()を使用している場合は、引き続きisomorphic-fetchまたはisomorphic-unfetchをインポートする必要があります。

この変更は完全に非破壊的であり、すべてのポリフィルは利用可能な最も仕様に準拠したバージョンで作られています。その結果、最新のブラウザでは本番バンドルから最大18kBのJavaScriptが削除されます。

ページ読み込みの最適化:FCPとTTIの改善

Next.jsはプリロードの実装を最適化して、FCPと全体的なTTIを削減しました。

ブラウザのバグを回避することで、(使用されている場合)CSSがJavaScriptよりも優先的に処理されるようになりました。これにより、First Contentful Paintが高速化され、エンドユーザーにとって視覚的に完成したWebサイトが大幅に高速になります。

さらに、ページプリフェッチを最適化して、低優先度のネットワークリクエストを使用するようにしました。

さらに、これらのリクエストはブラウザのアイドル時間中のみ行われるため、対話型になるまでの時間が短縮されます。これは、ブラウザが楽観的なプリフェッチよりもアプリケーションの対話性を優先するためです。

FCP/TTI Before and After Optimizations
FCP/TTIの最適化前と最適化後

最新のJavaScript機能のサポート

Next.jsには、最新のJavaScript機能を使用できる高度で最適化されたコンパイルパイプラインがあります。最近導入された最適化により、アプリケーションサイズが3~8%削減されました。

これらのJavaScript機能は、ブラウザの互換性を気にすることなく利用できます。コードは、(サポート終了バージョンを除く)すべてのブラウザをサポートするように自動的にコンパイルされるからです。これには、非同期/await (ES2017)オブジェクトのレスト/スプレッドプロパティ (ES2018)動的import() (ES2020)など、多くのES6+機能が含まれています!

今回のリリースでは、オプショナルチェイニング (Stage 4)Nullish合体演算子 (Stage 4)のサポートを発表できることを嬉しく思います。

pages/index.js
function Page(props) {
  return (
    <p>{props?.deeply?.nested?.value}</p>
    /* ⬆ If deeply.nested.value is not available it won't render */
  );
}
 
export default Page;

オプショナルチェイニング演算子 (?.)

pages/index.js
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スクリプトを含めるだけで済みます。

package.json
{
  "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で次のオプションを設定します。

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名以上のメンバーがいます。参加しましょう!

コミュニティの皆様、そしてこのリリースを形作るのに役立った外部からのフィードバックと貢献に感謝いたします。