Help us understand the problem. What is going on with this article?

Next.js 10 リリースノート全訳! 画像の自動最適化、i18n対応、アナリティクス、Eコマースほか

この記事は Next.js 10 リリースノートの日本語訳です。

10/27、Next.js 10 がリリースされました! :tada:

私はふだん Next.js で個人開発を行ったりしている者です。
Twitter もやっているのでよかったらフォローおねがいします! :nerd: @_thesugar_

よかったら Next.js チュートリアル(公式)の翻訳記事もどうぞ。
また、非公式ですが Next.js のドキュメントの翻訳プロジェクト も盛り上がっています! :octocat:

Next.js 10

Next.js 10 の機能をご紹介します:

ビルトインの画像コンポーネントと画像の自動最適化

Next.js で実現したい目標は、次の 2 つのことを改善することです: 開発者体験(DX)とユーザーエクスペリエンス(UX)。

今年、すでに DX および、あらゆる Next.js アプリのパフォーマンス向上の両方に重点的に投資を行なってきました。我々は、ブラウザが読み込まなくてはならない JavaScript の量を減らすことに焦点を当てました。

我々は、パフォーマンスと DX を改善するための 20 個を超える新しい機能 を導入しました。同時に、Next.js のコアを構成する JavaScript のサイズを 16 % 削減しました

1 月には、Google Chrome チームと協働して、比肩するものがないほどに優れた JavaScript のコード分割戦略を導入しました。

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

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

Web における画像

ブラウザが読み込まなくてはならない JavaScript の量を減らすことに焦点を当てた取組みはうまくいきましたが、Web を構成するものは JavaScript だけではありません: つまり、マークアップや画像も含まれています。

画像は Web ページのトータルのバイト数のうち、50 % を占めています。

画像は Largest Contentful Paint に大きく影響します。あるページが読み込まれるとき、画面に表示される最大の要素は画像であることが多いからです。Largest Contentful Paint とは、Google が彼らの検索アルゴリズムのランキングでまもなく使用するであろう Core Web Vitals です。

Web に存在する画像のうち半分は 1 MB 以上のサイズで、つまり Web での表示用に最適化されてはいないということです。

最近のユーザーはスマートフォンやタブレット、ノート PC を使って Web をブラウズしていますが、画像はまだ 1 つのサイズでそのすべてに対応しています。例えば、あるサイトで 2000 × 2000 ピクセルの画像を読み込んでも、スマートフォンではそれを 100 × 100 ピクセルでしか表示しません。

さらに、Web ページに存在する画像の 30 % は最初のビューポート外にあり、それはつまり、ユーザーがページ下部にスクロールするまで見られることのない画像をブラウザが読み込んでしまっているということです。

画像は widthheight 属性を持たないこともよくあり、ページが読み込まれたとき、画像が飛び跳ねてしまうことの原因になります。これは Cumulative Layout Shift という Core Web Vitals に悪影響を及ぼします。

世界中の Web サイトに存在する 99.7 % の画像は WebP のようなモダンな画像フォーマットを使用していません。

Web ページにおいてパフォーマンスに優れた方法で画像を使用するためにはいくつもの側面を考慮しなくてはなりません: サイズ、幅、遅延読み込み、そしてモダンな画像フォーマットなど。

画像を最適化するために開発者は複雑なビルドツールを設定しなくてはなりませんが、これらのツールは通常、外部のデータソースからの、ユーザーが投稿した画像まではカバーしきれないので、あらゆる画像を最適化することは不可能です。

こうした不可能な開発タスクが、必然的に、エンドユーザーにとってはストレスのたまる UX を与えることになってしまうのです。

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

Web においてパフォーマンスに優れた画像を実現するためのソリューション: Next.js の画像 (Image) コンポーネントと画像の自動最適化をここで発表します。

最も基本的には、Next.js の Image コンポーネントは HTML の <img> 要素をそのまま置き換えるだけのもので、モダン Web 用に進化したものです。

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

<Image src="/profile-picture.jpg" width="400" height="400">

Google Chrome のチームが、この React コンポーネントの作成を支援してくれ、デフォルト設定でベストプラクティスとなるようにすることで、ページのパフォーマンスを改善できるようになりました。

next/image コンポーネントを使用すると、画像は自動的に遅延読み込みされます。つまり、ユーザーが画像に近づいたときになってはじめて画像がレンダリングされます。これにより、先ほど、30 % の画像が最初のビューポート外にあると述べましたが、そうした画像たちが読み込まれるのを防ぎます。

画像の寸法が強制されるため、画像を読み込んだときに画像が飛び跳ねてしまうのではなく、画像に必要なスペースをすぐにブラウザがレンダリングすることができ、これによってレイアウトのずれを防げます。

HTML の <img> 要素における widthheight はレスポンシブなレイアウトまわりで色々と問題を引き起こす原因になりえますが、next/image を使う場合にはそのようなことはありませんnext/image を使うと、指定された widthheight のアスペクト比に基づいて画像は自動的にレスポンシブとなります。

開発者は、最初のビューポートに存在する画像をマークすることで、Next.js は自動的にそれらの画像を事前ローディングすることができます。最初のビューポートに画像を事前ローディングしておけば、Largetst Contentful Paint が最大 50 % まで改善するということが確認されています。

画像の自動最適化

HTML の <img> 要素から上記のような改善を経てもなお、まだ大きな問題があります。2000 × 2000 ピクセルの画像が、小さい画像しかレンダリングしないスマートフォンに送られてしまうという問題です。

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

ビルトインの画像最適化は自動的に WebP のようなモダンな画像フォーマットを提供しますが、これは JPEG より 30 % ほど軽量です(ブラウザが対応していれば)。ビルトインの画像最適化によって、将来の画像フォーマットを自動的に採用し、それらのフォーマットに対応しているブラウザに、それらのフォーマットの画像を送ることができます。

画像の最適化はあらゆる画像ソースに対して機能します。画像が CMS のような外部のデータソースから得られる場合でも最適化がなされるのです。

ビルド時に画像を最適化するのではなく、Next.js 10 では画像をオンデマンドで、つまりユーザーが画像をリクエストするときに最適化します。静的サイト生成や静的専用のソリューションとは異なり、10 個の画像を公開する場合でも 1,000 万個の画像を公開する場合でもビルドにかかる時間は増えません。

結論

新しい next/image コンポーネントと画像の自動最適化は UX を大幅に向上させる強力な新しい構成要素です。

next/image コンポーネントは自動的な遅延読み込みや、重要な画像の事前ローディング、デバイス間での正しいサイジング、モダンな画像フォーマットへの対応に対応しています。これらの機能はあらゆるソースからの画像に対して動作するのです。

こういった新しい構成要素を使うことで、あなたのアプリユーザーの UX がどれだけ速くなるのか楽しみです。

さらなる詳細は Next.js の Image コンポーネントと画像の自動最適化に関するドキュメントをご覧ください。

国際化に対応したルーティング

今年は、複数の企業やコミュニティのメンバーが、国際化 (internationalization; i18n) がどれほど重要であるかを我々のチームが理解する一助となってくれました。

たとえば、消費者の 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 のロケール識別子です。UTSロケール識別子とは、ロケールを定義するために標準化されたフォーマットです。

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

  • en-US - アメリカ合衆国で話されている英語
  • nl-NL - オランダで話されているオランダ語
  • nl - オランダ語。地域は限定せず。

ロケールを設定したら、サブパスによるルーティングかドメインによるルーティングかを選択することができます。

サブパスによるルーティング

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

たとえば、/nl-nl/blog/en/blog というように URL にロケールを挿入することができます。

ドメインによるルーティング

ドメインによるルーティングを利用すれば、ロケールをトップレベルのドメインにマッピングすることが可能です。たとえば 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 ヘッダーとマッチングされ、設定されたルーティングルールにしたがってリダイレクトされます。

検索エンジン最適化 (SEO)

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

Next.js はページの言語バリアントを認識しないので、next/head を使って hreflang メタタグを追加するかどうかはあなた次第です。hreflang についてもっと学ぶには Google Webmasters のドキュメントを参照してください。

Next.js における国際化対応の将来

国際化に対応したルーティングは、プロジェクトの国際化とローカライズをより簡単に行うための一連の機能の最初のものです。国際化に対応したルーティングは、React の国際化対応のためのライブラリの大多数と統合して使用することができます。

国際化に対応したルーティングの詳細を知りたい場合は、国際化に対応したルーティングのドキュメントをチェックしてください。

Next.js アナリティクス

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

Web サイトへの訪問者は、サイトのパフォーマンスに対してますます敏感になってきています。サイトを読み込むのに 3 秒以上かかると、50 % 超の訪問者は Web サイトから去ってしまいます。E コマースの場合は、ページ読み込みにかかる時間を 1/10 秒改善することでコンバージョンが 1 % 向上する結果になるということが広く知られています。

Web サイトの成功にはパフォーマンスがとても重要であるため、Next.js アナリティクスをリリースできることを誇りに思います。Next.js アナリティクスは実世界のパフォーマンス指標をトラッキングし、それによって得られた洞察を開発のワークフローにフィードバックするためのソリューションです。

Next.js アナリティクスを使うことで:

一度計測したきりではなく、継続的に計測することができます

開発機で計測を行うのではなく、あなたの Web サイトへの訪問者が実際に使用するデバイスから計測がなされます

Next.js アナリティクスは全体像に焦点を当て、Web サイトへの訪問者のことを深く理解し、アプリケーションがユーザーに対してどのようなパフォーマンスを発揮しているかを理解することを目的としたものです。

我々が実際のデータを収集することにこだわっているのは、貧弱なパフォーマンスの原因が必ずしもつねに明らかであるとは限らないからです。パフォーマンスの低下は、サードパーティのスクリプトやスタイルシート、あるいはファーストパーティのフォント、画像、ビデオ(大きすぎたり、低速だったりするもの)など、さまざまな原因により生じます。

Core Web Vitals

Google は、Web Performance Working Group と協働し、ユーザーがどのように Web サイトのパフォーマンスを体験しているかを正確に計測するための一連の指標を確立しました: その名も、Web Vitals です。

Web Vitals は、Web サイトを訪問したユーザーが体感するローディング速度、応答性、視覚的な安定性——これら 3 つはいずれも Web サイト全体の健全性に欠かせない要素です——をトラッキングするための指標です。

ユーザーが体感するローディング速度は、Largest Contentful Paint、つまり、いつページのすべてのコンテンツが表示されるかによって計測することができます。たとえば、スニーカーを購入するためのリンクを開いたとき、スニーカーとその価格、そしてカートに入れるボタンが表示されるまでの時間が LCP になります。

ページの応答性は、First Input Delay によって計測できます。これは、ページと最初のインタラクションを行うときに、ページが反応を返すまでユーザーがどれくらい待たなければならないかを測定するものです。たとえば、カートに入れるボタンをクリックしてから、カート内のアイテム数が増加するまでの時間が FID ということになります。

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

実際のユーザーのためにこれらの Web Vitals を継続的に測定し、これらの指標に適合するようにすることはきわめて重要です。これは、自分のサイトがユーザーにとってどのようなパフォーマンスを発揮しているかを真に知るただ一つの方法です。自分のサイトのパフォーマンスはユーザーが使っているデバイスやネットワークの状況、あるいはユーザーがページをどのように操作しているかによって大幅に変化します。パーソナライズされたコンテンツや広告を読み込むサイトでは、ユーザーによってパフォーマンスが大きく異なる場合があります。

エミュレートされたテストではこれらの重要なシグナルを捉えることができないのです。

Next.js アナリティクスを使えば、合成されたベンチマークではなく、実世界の知見を捉えることができます。これにより、時々行われるテストに頼るのではなく、計測の継続的な流れを可能にし、それを開発者のワークフローの一部とすることができます。

nextjs.org/analytics にアクセスして、アプリでそれを有効にする方法をさっそく学びましょう。

Next.js コマース

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

そのため、本日、BigCommerce と共同で、E コマースサイトのためのオールインワンのスターターキット Next.js Commerce をリリースしました。数回クリックするだけで、Next.js の開発者はクローンの作成からデプロイ、そしてフルカスタマイズが可能です。今すぐ nextjs.org/commerce から始めましょう。

React 17 サポート

React 17 では、Next.js に対しての破壊的な変更はありませんでしたが、メンテナンスのためにいくつか変更が必要な部分もありました。たとえば、peer の依存関係の更新などです。新しい JSX トランスフォーム は React 17 を使用すると自動的に有効になり、設定の変更はなんら必要ありません。

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

npm install next@latest react@latest react-dom@latest

getStaticProps / getServerSideProps の Fast Refresh

getStaticPropsgetServerSideProps 関数に変更を加えるとき、Next.js は自動的に関数を再実行し、新しいデータを適用するようになりました。このことにより、ページをリフレッシュすることなく素早く開発を繰り回すことができます。

getStaticProps および getServerSideProps についてより詳しく知るには、データフェッチングのドキュメントをご覧ください。

MDX のための Fast Refresh

@next/mdx によって Next.js を MDX と使用する際、MDX のコンテンツを変更すれば Fast Refresh が利用できるようになり、編集を行うたびにブラウザがページを再読み込みする必要がなくなりました。

MDX を Next.js と使うための設定を行う方法は、@next/mdx のドキュメントを参照してください。

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

サードパーティの CSS を React コンポーネントの中にインポートできるようになりました。これにより、単一のコンポーネントで使うためだけに取り込んだ CSS をコード分割することができます。たとえば、_app.js に CSS をインポートすることなく、react-datepicker ライブラリを使用できるようになりました:

import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'

Next.js が CSS のインポートをどのように扱っているか詳しく知るには CSS のビルトインサポートに関するドキュメントを参照してください。

href の自動解決

ダイナミックルーティングを使ったことがあれば、おそらく href 属性と as 属性の両方を next/link に与えなくてはならない状況に出くわしたことがあるでしょう。この場合、以下のようになります:

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

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

我々は、開発者体験 (DX) とエンドユーザーの UX を向上させることを主な目標として、この問題を解決することに数ヶ月前に着手しました。我々は、href が自動的に解決されるようなソリューションに向けて段階的に取り組んできました。

Next.js 10 の一部として、ほとんどのユースケースにおいては as 属性を使用する必要がなくなったことをここで発表します。これにより、開発者を感じていた問題を取り除き、エンドユーザーの UX を向上させることができます。

この変更は完全に後方互換性があり、現在 hrefas の両方を使っている場合、既存の振る舞いは保たれます。

href の自動解決を取り込むためには、next/link の使い方を、これまでは as 属性に与えていた値を href が持つように変更するだけです。

next/link とクライアント再度のルーティングについて詳しく知るためには、next/link のドキュメントをご参照ください。

@next/codemod CLI

我々は、幅広い後方互換性によって可能な限りスムーズに Next.js のアップグレードを行えることを約束します。この取組みは、非推奨となる機能をかなり少なくすることから始まり、その代わりに、新しくてより良いソリューションを導入します。この取組みに加えて、ローカルでの開発を再現するテストを含む、Next.js のすべての機能について幅広い統合テストを行なっています。

Next.js のある機能が非推奨となり、大規模なコードベースの変更が必要となる場合、我々のチームはその機能のための codemod を作成します。codemod とは、ソースコードをアップデートするためにプロジェクト上で実行できる自動化されたコード変換のことです。

たとえば以下のようなものがあります: 我々はアロー関数と無名関数を名前付き関数に更新するための codemod をリリースしました。この変換を行わないと、React Fast Refresh が関数を有効な React コンポーネントとして検出してくれないために必要となるものです。同様に、React フックの eslint のルールもそういった関数を React コンポーネントとして検出してくれません。

Next.js 10 では新しい Next.js codemods CLI ツールをリリースしています。このツールを使うと、1 つのコマンドを実行するだけでアプリケーションを更新することができます: npx @next/codemod <transform> <path>

codemod について詳しく知るには Next.js Codemod のドキュメントをチェックしてください。

getStaticPaths におけるフォールバックのブロック

Next.js 9.3 で getStaticPropsgetStaticPaths を導入しましたが、その中でgetStaticPaths から fallback プロパティを return するという機能がありました。fallback プロパティを使うことで、静的なページを追加的に生成する際、そのページ全体を再ビルドする必要がなくなります。最初は静的な HTML ファイルを提供し、その後のリクエストでは完全にレンダリングされたコンテンツに置き換えられます。過去数ヶ月、それに似ているけれども少しだけ異なる動作を求めている企業たちからたくさんのフィードバックを受けました: それは、ユーザーが初めてページに対してリクエストを行うときには、プリレンダリングをブロックしてほしいというものです。最初のレンダリングが行われたあと、そのページは後続のリクエストに対して再利用されてほしいというのです。

Next.js 10 ではこの問題を解決しています。

新しく、getStaticPaths における fallback: 'blocking' モードを発表します。これにより、ブラウザに静的なフォールバックページが送信することをブロックするような動作が可能になります。代わりに、最初のリクエストではプリレンダリングを待機します。

export function getStaticPaths() {
  return {
    // fallback 動作をブロックするモードを有効にする
    fallback: 'blocking'
  }
}

追加的な静的ページをインクリメンタルに生成するための fallback の動作について詳しく知るためには fallback のドキュメント を参照してください。

訳者注釈
ここは若干イメージが沸きづらいかもしれません(私の翻訳のぎこちなさもあり、、)。以下の例をご覧ください。fallbacktrue とすると、外部データの取得が必要な部分(ここでは japan という文字列)は最初表示されず、少しラグがあって表示されます。
fallback_true.gif
一方、fallback'blocking' とすると、外部データの取得が完了するまではレンダリングが行われない(待機する)ので、ユーザーの目には最初からレンダリングが完了した状態のページが表示されます。これがプリレンダリングをブロックする動作です。
fallback_blocking.gif
ちなみに、fallbackfalse とすると、事前に getStaticPathspaths で指定したパス以外に対してリクエストがあった場合、404 エラーとなります。

結論

Next.js の採用が継続的に伸びていることにワクワクしています。

  • これまでに 1,300 人 以上の実人数ベースでのコントリビューターがいて、9.5 のリリース以降では 120 人の新しいコントリビューターがいました。
  • GitHub では、このプロジェクトは 54,800 回 以上スターを付けられています。

GitHub Discussions で Next.js のコミュニティに参加しましょう。Discussions は、他の Next.js ユーザーとつながり、自由に質問をし、作品を共有できるコミュニティ空間です。

thesugar
東大工学部卒→金融機関のR&D部門で機械学習エンジニア→退職して無職。機械学習、フロントエンド開発、純粋関数型言語に興味があります。
https://thesugar.me
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away