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

2020年10月27日火曜日

Next.js 10

投稿者

Next.js 10を発表できることを嬉しく思います。このバージョンには以下の機能が含まれます。

組み込み画像コンポーネントと自動画像最適化

Next.js の目標は、開発者エクスペリエンスとユーザーエクスペリエンスの 2 つを向上させることです。

今年、私たちは開発者エクスペリエンスとすべての Next.js アプリケーションのパフォーマンス向上に多大な投資を行ってきました。ブラウザが読み込む JavaScript の量を減らすことに注力しました。

パフォーマンスと開発者エクスペリエンスを向上させる20以上の新機能を導入しました。同時に、Next.js コアの JavaScript サイズは16%削減されました。

1月には、Google Chrome チームと協力して、クラス最高の新しいJavaScriptコード分割戦略を導入しました。

例えば、Barnebys ではアプリケーションサイズが23%削減され、Sumup では最大のJavaScriptバンドルサイズが70%削減されました。これらの改善は、Next.js アプリケーションのコードを変更することなく達成されました。

企業は、Next.js を最新バージョンにアップグレードするだけで、この新しい戦略を自動的に採用しました。

Web 上の画像

ブラウザが読み込む JavaScript の量を減らすことに焦点を当てた努力は成果を上げていますが、Web は JavaScript だけではありません。マークアップと画像も含まれます。

画像は Web ページ全体のバイト数の 50% を占めます。

画像は、ページが読み込まれる際の最も大きな表示要素であることが多いため、Largest Contentful Paint に大きな影響を与えます。Largest Contentful Paint は、Google が間もなく検索ランキングに使用する Core Web Vitals の一つです。間もなく

画像の半分は 1MB を超えるサイズであり、Web 上での表示には最適化されていません。

現在、ユーザーは携帯電話、タブレット、ラップトップで Web を閲覧していますが、画像は依然としてすべて同じサイズです。例えば、サイトは 2000 x 2000 ピクセルの画像を読み込みますが、携帯電話では 100 x 100 ピクセルでしか表示されません。

さらに、Web ページ上の画像の 30% は初期ビューポートの外にあり、ユーザーがページをスクロールして初めて表示される画像をブラウザが読み込んでいることを意味します。

画像にはwidthheightプロパティがないことが多く、ページ読み込み時に画像が飛び跳ねる原因となります。これは、Cumulative Layout Shift Core Web Vital に悪影響を与えます。

Web サイト上の画像の 99.7% は、WebP のような最新の画像フォーマットを使用していません。

Web ページで画像をパフォーマンス良く使用するには、サイズ、重量、遅延読み込み、最新の画像フォーマットなど、多くの側面を考慮する必要があります。

開発者は画像を最適化するために複雑なビルドツールをセットアップする必要がありますが、これらのツールは通常、外部データソースから取得したユーザー提供の画像には対応していないため、すべての画像を最適化することができません。

この不可能な開発タスクは、必然的にユーザーにフラストレーションを与えるエクスペリエンスにつながります。

Next.js 画像コンポーネント

Web 上のパフォーマンスの高い画像に対するソリューションを発表できることを嬉しく思います。それは Next.js 画像コンポーネントと自動画像最適化です。

最も基本的なレベルでは、Next.js 画像コンポーネントは HTML<img> 要素のドロップイン代替であり、モダン Web に進化しています。

<img
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>
import Image from 'next/image';
<Image
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>;

Google Chrome チームは、ベストプラクティスをデフォルトにすることで、ページパフォーマンスを向上させるためにこの React コンポーネントの作成に協力しました。

next/imageコンポーネントを使用すると、画像は自動的に遅延読み込みされます。つまり、ユーザーが画像に近づいたときにのみレンダリングされます。これにより、初期ビューポート外の 30% の画像が読み込まれるのを防ぎます。

画像の寸法が強制されるため、ブラウザはレイアウトシフトを防ぐために、画像が読み込まれるときに飛び込んでくるのではなく、画像に必要なスペースをすぐにレンダリングできます。

HTML<img>要素のwidthheightはレスポンシブレイアウトで問題を引き起こす可能性がありますが、next/imageを使用する場合はそうではありませんnext/imageを使用すると、提供されたwidthheightからのアスペクト比に基づいて、画像は自動的にレスポンシブになります。

開発者は、初期ビューポートにある画像をマークできます。これにより、Next.js はこれらの画像を自動的にプリロードできます。初期ビューポートの画像をプリロードすると、Largest Contentful Paint が最大 50% 改善されることが示されています。

自動画像最適化

HTML<img>要素と比較してこれらの改善が行われても、依然として大きな問題があります。2000 x 2000 ピクセルの画像が、より小さい画像をレンダリングする携帯電話に送信されます。

Next.js 10 では、この問題も解決します。next/imageコンポーネントは、組み込みの画像最適化を通じて、自動的に小さいサイズを生成します。

組み込み画像最適化は、ブラウザがサポートしている場合、WebP のような最新の画像フォーマットで画像を自動的に配信します。これは JPEG よりも約 30% 小さくなります。これにより、Next.js は将来の画像フォーマットを自動的に採用し、それらをサポートするブラウザに配信できるようになります。

画像最適化は、任意の画像ソースで機能します。画像が CMS のような外部データソースから取得された場合でも、最適化されます。

Next.js 10 は、ビルド時に画像を最適化するのではなく、ユーザーが要求したときにオンデマンドで画像を最適化します。静的サイトジェネレータや静的専用ソリューションとは異なり、10 枚の画像でも 1000 万枚の画像でも、ビルド時間は増加しません。

結論

新しいnext/imageコンポーネントと自動画像最適化は、ユーザーエクスペリエンスを大幅に向上させる強力な新しいプリミティブです。

next/imageコンポーネントは、自動遅延読み込み、重要な画像のプリロード、デバイス間での正しいサイズ調整を処理し、最新フォーマットを自動的にサポートします。これらの機能は、任意のソースからの画像で動作します。

これらの新しいプリミティブにより、ユーザーエクスペリエンスがどれだけ向上するかを見るのを楽しみにしています。

詳細については、Next.js 画像コンポーネントと自動画像最適化のドキュメントをご覧ください。

国際化ルーティング

今年、いくつかの企業やコミュニティメンバーが、国際化の重要性について私たちのチームに理解を深めてくれました。

例えば、72% の消費者は、サイトが翻訳されていればサイトに留まる可能性が高く、55% の消費者は、母国語の eコマースサイトからしか購入しないと回答していることを学びました。

異なる国で市場展開を計画している場合、プロジェクトの国際化は成功のために不可欠です。

プロジェクトの国際化には、翻訳とルーティングの 2 つの主要な柱があります。

多くの React ライブラリはアプリケーションを翻訳可能に準備しますが、ほとんどはルーティングを手動で処理することを期待しており、一般的には 1 つのレンダリング戦略しか機能しません。

そのため、Next.js 10 の一部として、国際化ルーティングと言語検出の組み込みサポートをリリースします。

国際化ルーティングのこの組み込みサポートは、Next.js のハイブリッド戦略をサポートしているため、ページごとに静的生成またはサーバーレンダリングを選択できます。

Next.js 10 は、最も一般的な 2 つのルーティング戦略、サブパスルーティングとドメインルーティングをサポートしています。

どちらの戦略でも、まず Next.js の設定でロケールを構成します。

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    defaultLocale: 'en',
  },
};

ロケールはUTS ロケール識別子であり、ロケールを定義するための標準化された形式です。

一般的に、ロケール識別子は、言語、地域、スクリプトで構成され、ダッシュで区切られます: language-region-script。地域とスクリプトはオプションです。例

  • en-US - アメリカ合衆国で話されている英語
  • nl-NL - オランダで話されているオランダ語
  • nl - オランダ語、特定の地域なし

ロケールが構成されたら、サブパスまたはドメインルーティングを選択できます。

サブパスルーティング

サブパスルーティングは、URL にロケールを配置します。これにより、すべての言語を単一のドメインに配置できます。

例えば、URL に /nl-nl/blog/en/blog のようにロケールを挿入できます。

ドメインルーティング

ドメインルーティングでは、ロケールをトップレベルドメインにマッピングする方法を構成する必要があります。例えば、example.nlnl ロケールにマッピングでき、example.comen ロケールにマッピングできます。

ドメインルーティングには、ドメインのルーティング方法を認識するために追加の構成が必要です。

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl',
      },
    ],
  },
};

言語検出

Next.js 10 は、すべてのモダンブラウザがサポートしている Accept-Language ヘッダーに基づいた / ルートでの組み込み言語検出を備えています。構成されたロケールは Accept-Language ヘッダーと照合され、構成された戦略に従ってリダイレクトされます。

検索エンジン最適化

Next.js はユーザーが訪問したページの言語を認識するため、<html> タグに lang 属性が自動的に追加されます。

Next.js はページのバリエーションについては認識しないため、hreflang メタタグを next/head を使用して追加するのは開発者の責任です。hreflang については、Google Webmaster のドキュメント で詳細を確認できます。

Next.js における国際化の未来

国際化ルーティングは、プロジェクトの国際化とローカライズを容易にする一連の機能の最初のものです。国際化ルーティングにより、ほとんどの React 国際化ライブラリとの統合が可能になります。

国際化ルーティングの詳細については、国際化ルーティングのドキュメントをご覧ください。

Next.js スピードインサイト

Vercel では、測定できないものを修正できないことを知っています。

訪問者はサイトのパフォーマンスにますます敏感になっています。50% 以上が、読み込みに3秒以上かかる場合、サイトを放棄します。eコマースの場合、読み込み時間を 1/10 秒改善すると、コンバージョンが 1% 増加すると見つけました。

パフォーマンスは成功に不可欠であるため、Next.js Speed Insights をリリースできることを誇りに思います。これは、実際のパフォーマンスメトリックを追跡し、それらのインサイトを開発ワークフローにフィードバックするためのソリューションです。

Next.js Speed Insights を使用すると

一度測定するのではなく、継続的に測定します。

開発デバイスで測定するのではなく、訪問者が使用している実際のデバイスからの測定値が得られます。

Next.js Speed Insights は、全体像に焦点を当て、オーディエンスを深く理解し、アプリケーションがユーザーにどのようにパフォーマンスするかを理解することです。

パフォーマンスの低下の原因は常に最も明白ではないため、実際のデータを収集することに非常にこだわっています。パフォーマンスの低下は、サードパーティのスクリプトやスタイルシート、または大きすぎる、あるいは遅いファーストパーティのフォント、画像、ビデオなど、さまざまな場所から発生する可能性があります。

Core Web Vitals

Google は、Web Performance Working Group と協力して、Web サイトのパフォーマンスに対するユーザーエクスペリエンスを正確に測定するためのメトリックセットを確立しました。これは、Web Vitals と呼ばれています。Web Vitals は、Web サイトの全体的な健全性に不可欠な、知覚される読み込み速度、応答性、および視覚的安定性を追跡するメトリックです。

知覚される読み込み速度は、Largest Contentful Paint、またはページコンテンツがすべて表示されたときに測定できます。例えば、スニーカーを購入するためのリンクを開いたとき、スニーカー、価格、カートに追加ボタンが表示されるまでの時間が LCP です。

ページの応答性は、First Input Delay によって測定できます。これは、ユーザーがページへの最初のインタラクションの反応を見るために待つ必要がある時間を測定します。例えば、カートに追加をクリックしてからカート内のアイテム数がインクリメントされるまでの時間が FID です。

最後に、視覚的安定性は Cumulative Layout Shift、つまり要素が表示された後にどれだけ移動するかによって測定できます。例えば、画像が遅れて読み込まれたためにボタンが移動してしまい、タップしようとしてフラストレーションを感じた経験は誰にでもあるでしょう。これはレイアウトシフトです。

実際のユーザーに対するこれらの Web Vitals の継続的な測定と準拠は非常に重要です。これは、サイトがユーザーに対してどのようにパフォーマンスするかを真に知る唯一の方法です。サイトのパフォーマンスは、ユーザーのデバイスやネットワーク条件、またはページとの対話方法によって大きく異なる場合があります。パーソナライズされたコンテンツや広告を読み込むサイトも、ユーザーごとに大きく異なるパフォーマンスを経験する可能性があります。

エミュレートされたテストでは、これらの重要なシグナルをキャプチャできません。

Next.js Speed Insights では、合成ベンチマークの代わりに実際のインサイトをキャプチャできます。これは、定期的なテストに依存するのではなく、継続的な測定ストリームを可能にし、開発ワークフローの一部であることを保証します。

Next.js Speed Insights を使用すると、合成ベンチマークの代わりに実際のインサイトをキャプチャできます。これは、定期的なテストに依存するのではなく、継続的なストリームの測定を可能にし、開発ワークフローの一部であることを保証します

今すぐアプリケーションで有効にする方法については、nextjs.org/analyticsをご覧ください。

Next.js コマース

eコマースは Web の最も重要な用途の 1 つです。新しい Next.js 10 の機能は、eコマースのための強力な新しいツールです。

そのため、本日、BigCommerce との協力により、eコマースサイト向けのオールインワン React スターターキットである Next.js Commerce をリリースしました。数回のクリックで、Next.js 開発者はそれをクローン、デプロイ、および完全にカスタマイズできます。今すぐ nextjs.org/commerce で開始してください。

React 17 サポート

React 17 は Next.js に破壊的変更をもたらしませんでしたが、ピア依存関係の更新など、いくつかのメンテナンス変更が必要でした。新しいJSX変換は、React 17 を使用すると自動的に有効になります。設定の変更は必要ありません。新しいJSX変換

React 17 を使い始めるために必要なことは、Next.js と React をアップグレードすることだけです。

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

getStaticProps / getServerSideProps 高速リフレッシュ

getStaticProps および getServerSideProps 関数を編集する際、Next.js は関数を自動的に再実行し、新しいデータを適用するようになります。これにより、ページをリフレッシュすることなく、より迅速にイテレーションできるようになります。

getStaticProps および getServerSideProps については、データ取得のドキュメントをお読みください。

MDX の高速リフレッシュ

@next/mdx を介して Next.js を MDX と一緒に使用する場合、MDX コンテンツを変更すると Fast Refresh が活用され、編集時にブラウザがページをリロードする必要がなくなります。

Next.js と MDX のセットアップ方法については、@next/mdx のドキュメント を参照してください。

サードパーティReactコンポーネントからのCSSインポート

React コンポーネント内でサードパーティ CSS をインポートできるようになりました。これにより、単一のコンポーネント専用の CSS をコード分割できます。例えば、react-datepicker ライブラリを、_app.js で CSS をインポートする必要なく使用できるようになりました。

components/MyComponent.js
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
 
function MyComponent() {}

Next.js が CSS インポートをどのように処理するかについては、組み込み CSS サポートのドキュメントを参照してください。

href の自動解決

動的ルートを使用したことがある場合、next/linkhrefas の両方のプロパティを提供する必要があるケースに遭遇したことがあるかもしれません。それは次のようなものになります。

<Link href="/categories/[slug]" as="/categories/books" />

これにより、Next.js は動的パラメータの href を補間できましたが、開発者が as を追加し忘れたり、hrefas を追加したりすると、ページ遷移でクライアントサイドルーティングが使用されなくなるという問題が発生しました。

数ヶ月前、開発者エクスペリエンスとエンドユーザーエクスペリエンスの向上を主な目標として、この問題の解決に取り組みました。href が自動的に解決されるソリューションに段階的に取り組みました。

Next.js 10 の一部として、ほとんどのユースケースで as プロパティを使用する必要がなくなったことをお知らせできることを嬉しく思います。これにより、開発者の手間が省かれ、エンドユーザーエクスペリエンスが向上します。

この変更は完全に後方互換性があります。現在 hrefas の両方を使用している場合、既存の動作は維持されます。

自動 href 解決を採用するには、next/link の使用方法を変更し、as プロパティにあった値を保持する href のみを最初に使用するようにしてください。

<Link href="/categories/books" />

next/link とクライアントサイドルーティングについては、next/link のドキュメントを参照してください。

@next/codemod CLI

私たちは、広範な後方互換性を通じて、Next.js のアップグレードが可能な限りスムーズであることを保証することにコミットしています。このコミットメントは、新しい優れたソリューションに置き換えて、機能を非常にまれに非推奨にすることから始まります。このコミットメントに加えて、ローカル開発を再現するテストを含む、すべての Next.js 機能の広範な統合テストがあります。

Next.js の機能が非推奨になり、大規模なコードベースの変更が必要な場合、チームはそれに対応する codemod を作成します。codemod は、プロジェクト全体で実行してソースコードを更新できる自動コード変換です。

例:アロー関数と匿名関数を名前付き関数に更新するための codemod をリリースしました。この変換は、それ以外の場合、React Fast Refresh が関数を有効な React コンポーネントとして検出しないため必要です。同様に、React hooks ESLint ルールは、関数を React コンポーネントとして認識しません。

Next.js 10 では、新しい Next.js codemods CLI ツールをリリースします。これにより、単一のコマンドを実行してアプリケーションを更新できます: npx @next/codemod <transform> <path>

codemods については、Next.js Codemods のドキュメントを確認してください。

getStaticPaths のブロックフォールバック

Next.js 9.3 では、getStaticPropsgetStaticPaths を導入し、getStaticPathsfallback プロパティを返す機能も導入しました。fallback プロパティにより、完全な再ビルドなしで追加の静的ページを生成できます。初期リクエストでは静的HTMLファイルが配信され、その後のリクエストで完全にレンダリングされたコンテンツに置き換えられます。過去数ヶ月間、企業から同様の、しかしわずかに異なる動作を望む多くのフィードバックがありました。それは、ユーザーが初めてページをリクエストしたときのブロックプリレンダリングです。その初期レンダリングの後、ページは後続のリクエストのために再利用されます。

Next.js 10 では、このケースを解決します。

getStaticPaths の新しい fallback: 'blocking' モードを発表できることを嬉しく思います。これは、静的フォールバックがブラウザに送信されないブロック動作を有効にします。代わりに、初期リクエストはプリレンダリングのために待機されます。

pages/posts/[id].js
export function getStaticPaths() {
  return {
    // enables blocking mode for the fallback behavior
    fallback: 'blocking',
  };
}

増分静的ページ生成のための fallback 動作については、fallback のドキュメントを参照してください。

getStaticProps / getServerSideProps のリダイレクトおよび notFound サポート

getStaticProps および getServerSideProps の導入以降、ユーザーがリダイレクトや 404 応答を返す必要があるケースがいくつか見られました。これらのケースを簡素化するために、getStaticProps および getServerSideProps から notFound および redirect という 2 つの新しいフィールドを返すことができるようになりました。

notFound サポート

notFound フィールドを true で返すと、デフォルトの 404 ページがステータスコード 404 で返されます。これにより、SSG で追加のページを生成し、404 ページを手動でレンダリングする必要がなくなります。

pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns the default 404 page with a status code of 404
    notFound: true,
  };
}

redirect サポート

リダイレクトを返すことができるようになりました。これには destination と、リダイレクトが永続的かどうか (例: permanent: true) が含まれます。デフォルトのステータスコードの代わりに特定のステータスコードを使用する必要がある場合は、オプションで statusCode も返すことができます。

pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns a redirect to an internal page `/another-page`
    redirect: {
      destination: '/another-page',
      permanent: false,
    },
  };
}
pages/posts/[id].js
export function getServerSideProps() {
  return {
    // returns a redirect to an external domain `example.com`
    redirect: {
      destination: 'https://example.com',
      permanent: false,
    },
  };
}

結論

Next.js の採用が引き続き拡大していくのを楽しみにしています。

  • 1,300 を超える独立した貢献者があり、9.5 リリース以降、120 を超える新しい貢献者があります。
  • GitHub では、プロジェクトは 54,800 回以上スターされています。

GitHub Discussions で Next.js コミュニティに参加してください。GitHub Discussions。 Discussions は、他の Next.js ユーザーとつながり、自由に質問したり、作業を共有したりできるコミュニティスペースです。

クレジット

このリリースを形作った、外部からのフィードバックや貢献を含む、コミュニティに感謝します。

このリリースは、@ijjk、@adebiyial、@elliottsj、@saintmalik、@HaNdTriX、@prateekbh、@amirsaeed671、@paambaati、@imagentleman、@gregrickaby、@Janpot、@atcastle、@Kirkhammetz、@remorses、@davidsonsns、@kmkzt、@slawekkolodziej、@Timer、@styfle、@timneutkens、@ykzts、@ashconnell、@orYoffe、@lfades、@justinwhall、@fbaiodias、@ludofischer、@felipeguilhermefs、@gr-qft、@TasukuUno、@YichiZ、@weichienhung、@seosmmbusiness、@HsuTing、@gsimone、@peduarte、@ztanner、@neighborhood999、@chibicode、@merceyz、@opudalo、@lunchboxav、@mohsen1、@akd-io、@justman00、@helloworld、@devknoll、@borekb、@ArthurMaverick、@sakito21、@TrySound、@omBratteng、@svenheden、@hallaji、@kettanaito、@vvo、@m-lautenbach、@jensmeindertsma、@Zeko369、@longlho、@stefanprobst、@laugharn、@sdornan、@daneroo、@mohd-akram、@austingmhuang、@sphilee、@devinekadeni、@Bacher、@nghiepit、@tomasdisk、@leader22、@paulogdm、@284km、@belgattitude、@geritol、@stigkj、@sampoder、@samrobbins85、@Pitasi、@digitalPlayer1125、@timfee、@plug-n-play、@philihp、@leerob、@dylanjha、@Kerumen、@rdimaio、@jorisw、@zerbinidamata、@jamesgeorge007、@Jashnm、および @futantan の貢献によって実現しました!