画像最適化

Web Almanacによると、画像は一般的なウェブサイトのページ重量の大部分を占め、ウェブサイトのLCPパフォーマンスに大きな影響を与える可能性があります。

Next.jsのImageコンポーネントは、HTMLの<img>要素を自動画像最適化機能で拡張します:

  • サイズ最適化: WebPやAVIFなどの最新画像フォーマットを使用して、各デバイスに適切なサイズの画像を自動的に提供
  • 視覚的安定性: 画像の読み込み時にレイアウトシフトを自動的に防止
  • ページ読み込みの高速化: ブラウザのネイティブな遅延読み込みを使用して、ビューポートに入った時のみ画像を読み込み、オプションでぼかしプレースホルダーを表示
  • アセットの柔軟性: リモートサーバーに保存された画像でもオンデマンドでリサイズ可能

🎥 動画: next/imageの使用方法について詳しく学ぶ → YouTube (9分).

使用方法

import Image from 'next/image'

その後、画像のsrc(ローカルまたはリモート)を定義できます。

ローカル画像

ローカル画像を使用するには、.jpg.png.webp画像ファイルをimportします。

Next.jsはインポートされたファイルに基づいて、自動的に画像のwidthheightを決定します。これらの値は、画像の読み込み中に累積レイアウトシフトを防ぐために使用されます。

pages/index.js
import Image from 'next/image'
import profilePic from '../public/me.png'

export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="著者の写真"
      // width={500} 自動的に提供
      // height={500} 自動的に提供
      // blurDataURL="data:..." 自動的に提供
      // placeholder="blur" // 読み込み中のオプションのぼかし効果
    />
  )
}

警告: 動的なawait import()require()はサポートされていません。ビルド時に分析できるように、importは静的である必要があります。

リモート画像

リモート画像を使用する場合、srcプロパティはURL文字列である必要があります。

Next.jsはビルド時にリモートファイルにアクセスできないため、widthheight、およびオプションのblurDataURLプロパティを手動で指定する必要があります。

widthheight属性は、画像の正しいアスペクト比を推測し、画像の読み込みによるレイアウトシフトを防ぐために使用されます。widthheightは、画像ファイルのレンダリングサイズを決定するものではありません。画像サイズ設定について詳しく学びます。

app/page.js
import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="https://s3.amazonaws.com/my-bucket/profile.png"
      alt="著者の写真"
      width={500}
      height={500}
    />
  )
}

画像の最適化を安全に許可するには、next.config.jsでサポートするURLパターンのリストを定義します。悪意のある使用を防ぐために、できるだけ具体的にしてください。たとえば、次の設定では特定のAWS S3バケットからのみ画像を許可します:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
  },
}

remotePatterns設定について詳しく学びます。画像srcに相対URLを使用したい場合は、loaderを使用します。

ドメイン

組み込みのNext.js画像最適化APIを使用しながらリモート画像を最適化したい場合があります。これを行うには、loaderをデフォルト設定のままにし、Imageのsrcプロパティに絶対URLを入力します。

悪意のあるユーザーからアプリケーションを保護するために、next/imageコンポーネントで使用する予定のリモートホスト名のリストを定義する必要があります。

remotePatterns設定について詳しく学びます。

ローダー

前の例では、ローカル画像に対して部分的なURL("/me.png")が提供されていました。これはローダーアーキテクチャによって可能になります。

ローダーは、画像のURLを生成する関数です。提供されたsrcを変更し、異なるサイズで画像をリクエストするための複数のURLを生成します。これらの複数のURLは自動的なsrcset生成に使用されるため、サイトの訪問者にはビューポートに適したサイズの画像が提供されます。

Next.jsアプリケーションのデフォルトローダーは、組み込みの画像最適化APIを使用します。これはウェブ上のどこからでも画像を最適化し、Next.jsウェブサーバーから直接提供します。CDNや画像サーバーから直接画像を提供したい場合は、数行のJavaScriptで独自のローダー関数を記述できます。

loader propで画像ごとにローダーを定義するか、loaderFile設定でアプリケーションレベルで定義できます。

優先度

Largest Contentful Paint (LCP)要素となる画像にpriorityプロパティを追加する必要があります。これにより、Next.jsは画像の読み込みを特別に優先し(例えばプリロードタグや優先ヒントを通じて)、LCPの大幅な向上につながります。

LCP要素は通常、ページのビューポート内で表示される最大の画像またはテキストブロックです。next devを実行すると、LCP要素がpriorityプロパティなしの<Image>である場合、コンソール警告が表示されます。

LCP画像を特定したら、次のようにプロパティを追加できます:

app/page.js
import Image from 'next/image'

export default function Home() {
  return (
    <>
      <h1>マイホームページ</h1>
      <Image
        src="/me.png"
        alt="著者の写真"
        width={500}
        height={500}
        priority
      />
      <p>私のホームページへようこそ!</p>
    </>
  )
}

優先度についての詳細は、next/imageコンポーネントドキュメントをご覧ください。

画像サイズ設定

画像がパフォーマンスに悪影響を与える最も一般的な方法の1つは、読み込み時にページ上の他の要素を押しのけるレイアウトシフトです。このパフォーマンス問題はユーザーにとって非常に煩わしいため、Cumulative Layout Shiftという独自のCore Web Vitalがあります。画像ベースのレイアウトシフトを避ける方法は、常に画像のサイズを設定することです。これにより、ブラウザは画像が読み込まれる前に正確に十分なスペースを確保できます。

next/imageは優れたパフォーマンス結果を保証するように設計されているため、レイアウトシフトに寄与する方法で使用することはできず、次の3つの方法のいずれかでサイズを設定する必要があります

  1. 静的インポートを使用して自動的に
  2. widthheightプロパティを含めて明示的に
  3. fillを使用して暗黙的に(親要素を埋めるように画像を拡大)

画像のサイズがわからない場合はどうすればよいですか?

画像のサイズがわからないソースから画像にアクセスする場合、いくつかの方法があります:

fillを使用する

fillプロパティを使用すると、親要素によって画像のサイズが決まります。sizesプロパティを使用してメディアクエリのブレークポイントに合わせ、画像の親要素にページ上のスペースを与えるCSSを検討してください。fillcontaincoverobject-fitを使用したり、object-positionを使用して画像がそのスペースをどのように占有するかを定義することもできます。

画像を正規化する

制御可能なソースから画像を提供している場合は、画像パイプラインを変更して特定のサイズに画像を正規化することを検討してください。

API呼び出しを変更する

アプリケーションがAPI呼び出し(CMSなど)を使用して画像URLを取得している場合、URLと一緒に画像の寸法も返すようにAPI呼び出しを変更できる場合があります。

提案された方法のいずれも画像のサイズ設定に適していない場合、next/imageコンポーネントは標準の<img>要素と一緒にページ上でうまく動作するように設計されています。

スタイリング

Imageコンポーネントのスタイリングは通常の<img>要素のスタイリングと似ていますが、いくつかのガイドラインに注意する必要があります:

  • styled-jsxではなくclassNameまたはstyleを使用します。
    • ほとんどの場合、classNameプロパティを使用することをお勧めします。これはインポートされたCSSモジュールグローバルスタイルシートなどにすることができます。
    • インラインスタイルを割り当てるためにstyleプロパティを使用することもできます。
    • styled-jsxは現在のコンポーネントにスコープされているため使用できません(スタイルをglobalとマークしない限り)。
  • fillを使用する場合、親要素はposition: relativeを持っている必要があります
    • このレイアウトモードで画像要素を適切にレンダリングするために必要です。
  • fillを使用する場合、親要素はdisplay: blockを持っている必要があります
    • これは<div>要素のデフォルトですが、それ以外の場合は指定する必要があります。

レスポンシブ

親コンテナの幅と高さを埋めるレスポンシブ画像
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Responsive() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <Image
        alt="山"
        // 画像をインポートすると
        // 自動的に幅と高さが設定されます
        src={mountains}
        sizes="100vw"
        // 画像を全幅で表示
        style={{
          width: '100%',
          height: 'auto',
        }}
      />
    </div>
  )
}

コンテナを埋める

親コンテナの幅を埋める画像グリッド
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Fill() {
  return (
    <div
      style={{
        display: 'grid',
        gridGap: '8px',
        gridTemplateColumns: 'repeat(auto-fit, minmax(400px, auto))',
      }}
    >
      <div style={{ position: 'relative', height: '400px' }}>
        <Image
          alt="山"
          src={mountains}
          fill
          sizes="(min-width: 808px) 50vw, 100vw"
          style={{
            objectFit: 'cover', // cover, contain, none
          }}
        />
      </div>
      {/* グリッド内の他の画像... */}
    </div>
  )
}

背景画像

ページの全幅と高さを占める背景画像
import Image from 'next/image'
import mountains from '../public/mountains.jpg'

export default function Background() {
  return (
    <Image
      alt="山"
      src={mountains}
      placeholder="blur"
      quality={100}
      fill
      sizes="100vw"
      style={{
        objectFit: 'cover',
      }}
    />
  )
}

さまざまなスタイルで使用されたImageコンポーネントの例については、Image Component Demoを参照してください。

その他のプロパティ

next/imageコンポーネントで利用可能なすべてのプロパティを表示します。

設定

next/imageコンポーネントとNext.js画像最適化APIは、next.config.jsファイルで設定できます。これらの設定により、リモート画像を有効にしたり、カスタム画像ブレークポイントを定義したり、キャッシュ動作を変更したりできます。

詳細については、完全な画像設定ドキュメントをお読みください。