言語を切り替える
テーマを切り替える

Next.js 画像最適化完全攻略:Image コンポーネントの正しい使い方

Lighthouse テストスコア:62点。

この数字を見て、私は数秒間画面を見つめて固まりました。2週間かけて作った Next.js プロジェクトのパフォーマンススコアが、やっと及第点だったのです。Performance パネルを開くと、最大の問題は一目瞭然でした——LCP(Largest Contentful Paint)が 4.8秒。原因はすべて画像でした。

正直、当時は混乱しました。Next.js を使っているのだから、フレームワークが勝手に最適化してくれるのでは? しかしコードを確認すると、トップページの大きなヒーロー画像に、最も原始的な <img> タグを使っていました。EC サイトの商品一覧ページでは数十枚の商品画像を、サーバーから直接リサイズなしの原寸大(1枚 3-4MB)で読み込んでいました。

その後、Next.js は強力ですが、画像の最適化には Image コンポーネントを能動的に使う必要があることを知りました。正しく使えば、画像サイズを 60-80% 削減し、LCP を 2秒以内に抑えることができます。

問題なのは、多くの人が私と同じように、Image コンポーネントを使っても様々な落とし穴にはまることです。リモート画像で “Un-configured Host” エラーが出たり、ページ読み込み時に画像領域がガクガク動いたり、設定項目が多すぎて使い方が分からなかったり。この記事では、私が踏んだこれらすべての落とし穴とその解決策を整理し、ゼロから Next.js Image コンポーネントの正しい使い方を教えます。

なぜ Next.js Image コンポーネントを使うべきか?

普通の img タグの3つの落とし穴

「画像なんて <img src="xxx"> でいいじゃないか」と思うかもしれません。私も最初はそう思っていました。パフォーマンステストをするまでは。

第1の落とし穴:フォーマットが最適化されず、帯域を無駄にする

普通の img タグは、指定されたフォーマットをそのまま表示します。3MB の PNG をアップロードすれば、ユーザーは 3MB ダウンロードします。現在のブラウザはほぼ WebP をサポートしており(JPEG より 30% 小さい)、AVIF 対応ならさらに 40% 削減できます。しかし img タグはこれらを考慮せず、ただ指定されたファイルを読み込むだけです。

第2の落とし穴:画面サイズに関係なく、同じ画像を読み込む

これはモバイルで顕著です。2000x1500 の高解像度画像を置いておくと、ユーザーのスマホ画面が 375px 幅しかなくても、ブラウザは完全なサイズの画像をダウンロードしてから縮小表示します。通信量の無駄であり、読み込みも遅くなります。

第3の落とし穴:レイアウトシフト(CLS)による不快感

Web ページを開いてボタンをクリックしようとした瞬間、画像が読み込まれてページ全体が下にズレ、別の場所をクリックしてしまった経験はありませんか? これが CLS(Cumulative Layout Shift)問題です。Google はこれを Core Web Vitals の核心指標の一つとしており、SEO 順位に直結します。

Image コンポーネントの自動最適化能力

Next.js の Image コンポーネントは、これらの問題を解決するために設計されています。単なる img タグのラッパーではなく、完全な画像最適化ソリューションです。

自動フォーマット選択

Image コンポーネントはユーザーのブラウザの Accept ヘッダーを確認し、サポートされているフォーマットを自動判断します。AVIF 対応なら AVIF、WebP 対応なら WebP、どちらもダメなら元のフォーマットを提供します。このロジックは完全自動で、コードを書く必要はありません。

以前テストしたところ、500KB の JPEG が自動変換で WebP では 180KB、AVIF では 120KB になりました。サイト上に数十、数百枚の画像がある場合、どれだけの帯域節約になるか想像してみてください。

レスポンシブ読み込み

Image コンポーネントはユーザーデバイスの画面サイズに応じて、適切なサイズの画像を自動生成して読み込みます。スマホユーザーには 375px 幅、デスクトップユーザーには 1920px 幅の画像を表示します。これは srcset という機能で、普通の img タグでも可能ですが、手動で大量の設定を書く必要があります。Image コンポーネントなら全自動です。

遅延読み込み(Lazy Loading)

デフォルトでは、Image コンポーネントは視口(ビューポート)に入った画像のみを読み込みます。ページ下部の画像は、ユーザーがスクロールして到達するまで読み込まれません。この機能により、初回読み込みのデータ量が大幅に減り、ページ表示速度が劇的に向上します。

データによると、Next.js Image コンポーネントを正しく使用すれば、画像サイズを 60-80% 削減し、LCP 指標を 2.5秒以下に抑え、CLS をほぼゼロにできます。これは理論値ではなく、私の実際のプロジェクトでの測定値です。

基礎的な使い方:ローカル画像 vs リモート画像

Image コンポーネントを使い始めた多くの人(私を含む)が最初に戸惑うのが、「なぜ一部の画像は直接使えるのに、他はエラーになるのか?」という点です。主な理由は、ローカル画像とリモート画像の処理方法の違いです。

ローカル画像:最もシンプルなシナリオ

ローカル画像とはプロジェクト内に保存された画像ファイルのことです。2つの一般的な方法があります。

方法1:import インポート(推奨)

import heroImage from '/public/images/hero.jpg'
import Image from 'next/image'

export default function Home() {
  return (
    <Image
      src={heroImage}
      alt="Hero image"
    />
  )
}

この方法が最も簡単です。Next.js はビルド時に画像の幅と高さを自動的に読み取るため、widthheight を書く必要すらありません。私は現在、ローカル画像はほぼこの方法で処理しています。

方法2:パスを直接指定

<Image
  src="/images/hero.jpg"
  width={1920}
  height={1080}
  alt="Hero image"
/>

画像が public フォルダにある場合は直接パスを指定できます。ただし、この方法では手動で幅と高さを指定する必要があり、忘れるとエラーになります。

リモート画像:最も落とし穴が多い場所

リモート画像とは外部 URL から読み込む画像のことです(例:クラウドストレージ上の画像など)。このシナリオが最も問題を起こしやすいです。

よくあるエラー:“Un-configured Host”

<Image
  src="https://images.unsplash.com/photo-123456"
  width={800}
  height={600}
  alt="Sample image"
/>

このように直接書くと、十中八九このエラーに遭遇します:

Error: Invalid src prop (https://images.unsplash.com/photo-123456) on `next/image`, 
hostname "images.unsplash.com" is not configured under images in your `next.config.js`

なぜでしょうか? Next.js は、悪意のあるユーザーがあなたのサーバーを利用して任意の URL の画像を最適化し、サーバーリソースをタダ乗りすることを懸念しているからです。そのため、どのドメインの画像を最適化して良いかを明示的に宣言する必要があります。

正しい対処法:remotePatterns の設定

next.config.js に以下の設定を追加します(Next.js 14+ 推奨):

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.unsplash.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
  },
}

module.exports = nextConfig

各設定項目の意味:

  • protocol:https または http(通常は https)
  • hostname:画像ドメイン、完全一致が必要
  • port:ポート番号、通常は空
  • pathname:パス一致ルール、/** は全パス、特定のパスに制限も可能

設定後は開発サーバーを再起動してください。設定ファイルの変更は再起動するまで反映されません。私は最初、設定を変更しても再起動せず、「設定が効かない!」と30分無駄にしました。

旧版の設定方法(非推奨)

一部のチュートリアルで domains 設定を見かけるかもしれません:

module.exports = {
  images: {
    domains: ['images.unsplash.com', 's3.amazonaws.com'],
  },
}

この書き方は Next.js 14 以降非推奨です。まだ使えますが、remotePatterns への移行を推奨します。remotePatterns の方が安全で、パス範囲を具体的に制限できるからです。

幅と高さが必須な理由

ローカル画像を import する場合を除き、リモート画像でもローカル画像のパス指定でも、widthheight を手動指定する必要があります。これは CLS(レイアウトシフト)を防ぐためです。

ブラウザは画像を読み込む前に、その画像がどれだけのスペースを占めるかを知っておく必要があります。そうしないと事前にスペースを確保できず、画像ダウンロード後にレイアウトを調整するため、ページがガクッと動いてしまいます。

「レスポンシブ対応で幅が変わるのに、どうやって固定の幅と高さを指定するの?」と思うかもしれません。これについては後述する fill 属性で解決します。

レイアウトシフト(CLS)の解決

ページがガクガク動くのは本当に不快です。以前作ったニュースサイトで、ユーザーから「タイトルをクリックしようとしたら画像が出てきて広告をクリックしてしまった」という苦情が殺到しました。CLS という指標を詳しく調べて初めて、重要性に気づきました。

CLS とは何か、なぜ重要か

CLS(Cumulative Layout Shift)は累積レイアウトシフトと訳されます。簡単に言えば、ページ読み込み中に要素の位置がどれだけ突然移動したかを表す指標です。

Google は CLS を Core Web Vitals の3大核心指標の一つとしており、SEO 順位に直結します。CLS スコアが 0.1 を超えると「悪い」、0.1 以下なら「良い」とされます。ページ内に10〜20枚の画像があり、それぞれが読み込み時に画面をガクつかせれば、CLS は跳ね上がります。

さらに重要なのはユーザー体験です。私自身、いつまでもガタガタ動くページに遭遇したら、中身を見る前に閉じてしまいます。

Image コンポーネントはどうやって CLS を防ぐか

Next.js の Image コンポーネントが CLS を防ぐ核心原理はシンプルです:事前にスペースを確保することです。

Image コンポーネントに widthheight を設定すると、ブラウザは画像ダウンロード前にページ上で対応するホワイトスペースを確保します。画像読み込みが完了するとそこにポイっと入るだけなので、レイアウトは微動だにしません。

<Image
  src="/product.jpg"
  width={400}
  height={300}
  alt="Product image"
/>

このコードでは、ブラウザはまず 400x300 のプレースホルダーを描画し、それから画像読み込みを開始します。CLS 値はゼロになります。

問題は、現代の Web はレスポンシブデザインであり、画像の幅は画面サイズに応じて変わるということです。固定サイズでは対応できません。

レスポンシブ画像の正解:fill 属性

レスポンシブ画像のために、Next.js は fill 属性を提供しています。この属性は画像を親コンテナいっぱいに広げ、サイズ制御を CSS(親コンテナ)に委ねます。

<div style={{ position: 'relative', width: '100%', height: '400px' }}>
  <Image
    src="/hero.jpg"
    fill
    style={{ objectFit: 'cover' }}
    alt="Hero image"
  />
</div>

重要なポイント:

  1. 親コンテナには position: relative が必須:画像は親を基準に絶対配置されます
  2. 親コンテナには明確な高さが必要height: auto はダメです。具体的な数値かパーセンテージが必要です
  3. objectFit で画像の収まり方を制御cover はトリミングして埋め尽くし、contain は全体を表示し余白を残します

この方法なら、ブラウザは親コンテナの高さを見てスペースを確保でき、CLS を防止できます。

sizes 属性:ブラウザに最適な画像サイズを教える

fill 属性を使うときは、sizes 属性も併用すべきです。そうしないと Next.js はどのサイズの画像を生成していいか分からず、デフォルト(画面幅いっぱい)を使ってしまいます。

<div style={{ position: 'relative', width: '100%', height: '400px' }}>
  <Image
    src="/hero.jpg"
    fill
    sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
    style={{ objectFit: 'cover' }}
    alt="Hero image"
  />
</div>

sizes 属性の意味:

  • 画面幅 ≤768px 時、画像は視口の 100% 幅
  • 画面幅 768px-1200px 時、画像は視口の 50% 幅
  • 画面幅 >1200px 時、画像は視口の 33% 幅

Next.js はこの設定に基づいて複数のサイズの画像を生成し、ブラウザが自動的に最適なものを選択します。スマホユーザーは巨大なデスクトップ画像を落とさずに済み、通信量と速度が改善します。

実践ケース:シーン別対応

ヒーロー画像(全幅、ファーストビュー)

<div style={{ position: 'relative', width: '100%', height: '60vh' }}>
  <Image
    src="/hero.jpg"
    fill
    priority
    sizes="100vw"
    style={{ objectFit: 'cover' }}
    alt="Hero image"
  />
</div>

ここでは priority 属性(後述)を使い、最優先で読み込ませます。sizes="100vw" は常に画面全幅であることを示します。

記事・商品サムネイル(固定サイズ)

<Image
  src={post.thumbnail}
  width={300}
  height={200}
  alt={post.title}
/>

サムネイルのサイズが決まっているなら、直接 widthheight を指定するのが一番簡単です。

製品リスト(レスポンシブグリッド)

<div style={{ position: 'relative', width: '100%', paddingBottom: '100%' }}>
  <Image
    src={product.image}
    fill
    sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
    style={{ objectFit: 'cover' }}
    alt={product.name}
  />
</div>

paddingBottom: '100%' で正方形のコンテナ(アスペクト比 1:1)を作り、製品画像を表示します。モバイルで1列、タブレットで2列、デスクトップで3列といったレイアウトに最適です。

パフォーマンス最適化の核心設定

基本と CLS 対策を抑えたら、次はパフォーマンスをさらに引き上げるための設定です。

priority:首屏の重要画像を優先する

デフォルトでは、Image コンポーネントは遅延読み込み(Lazy Load)ですが、首屏のヒーロー画像やロゴなどは即座に表示されるべきです。

そこで priority 属性を使います:

<Image
  src="/hero.jpg"
  width={1920}
  height={1080}
  priority
  alt="Hero image"
/>

priority を付けると:

  1. 遅延読み込みを無効化し、即時ロード開始
  2. HTML <head> に preload タグを挿入し、ブラウザに「最重要」と伝える
  3. LCP 指標が劇的に改善する

私が最適化を行った際、トップページのヒーロー画像に priority を付けただけで LCP が 3.8秒から 2.1秒に短縮されました。効果絶大です。

いつ priority を使うか?

  1. ヒーロー画像
  2. サイトロゴ(大きい場合)
  3. 記事詳細ページのトップ画像
  4. その他 LCP 要素になりうる画像

「全部に付ければ速くなる?」と思うかもしれませんが、逆効果です。ブラウザが全ての画像を同時ダウンロードしようとして帯域が詰まります。本当に重要な画像だけに絞ってください。

Next.js 16 の変更点

Next.js 16(RC 版)から、priority 属性は preload 属性に変更される予定です。最新版を使う場合は:

<Image
  src="/hero.jpg"
  width={1920}
  height={1080}
  preload
  alt="Hero image"
/>

またはより柔軟な書き方:

<Image
  src="/hero.jpg"
  width={1920}
  height={1080}
  loading="eager"
  fetchPriority="high"
  alt="Hero image"
/>

loading:読み込み戦略の制御

loading 属性には2つの値があります:

  • lazy(デフォルト):遅延読み込み。視口インのみダウンロード
  • eager:即時読み込み。場所に関わらずダウンロード

基本は lazy で十分です。首屏の重要画像だけ eager(または priority)にします。

// ページ下部の関連画像:デフォルトの lazy
<Image src="/related-1.jpg" width={300} height={200} alt="Related post" />

// ファーストビュー画像:eager
<Image src="/main-content.jpg" width={800} height={600} loading="eager" alt="Main content" />

quality:画質とサイズのバランス

quality 属性は圧縮品質を制御します(1-100、デフォルト 75)。

<Image
  src="/product.jpg"
  width={800}
  height={600}
  quality={90}
  alt="Product image"
/>

品質が高いほど綺麗ですがファイルも大きくなります。経験則:

  • 首屏の重要画像quality={90}(高品質維持)
  • 一般画像quality={75}(デフォルト、バランス型)
  • サムネイル・背景quality={60}(帯域節約)

テストの結果、90 から 75 に下げても目視ではほぼ分からないのにサイズは 30% 減りました。75 から 60 でも許容範囲で、さらに 20% 減りました。

重要:Next.js 16 から quality は必須項目になります。これは、ユーザーが URL パラメータで無制限に画質要求をしてサーバー負荷をかけるのを防ぐためです。

自動フォーマット選択:WebP vs AVIF

この機能は完全自動です。設定不要で、Next.js がブラウザの Accept ヘッダーを見て最適フォーマットを返します。

  • AVIF 対応 → AVIF(最小、エンコード遅め)
  • WebP 対応 → WebP(小、互換性良し)
  • 非対応 → 元フォーマット(JPEG/PNG)

AVIF は WebP よりさらに 30-40% 小さいです。主要ブラウザ(Chrome 85+, Firefox 93+, Safari 16+)は既に対応済みなので安心です。

実戦設定例

これらを組み合わせた、シーン別の書き方です:

トップページヒーロー画像(優先、高品質)

<div style={{ position: 'relative', width: '100%', height: '60vh' }}>
  <Image
    src="/hero.jpg"
    fill
    priority
    quality={90}
    sizes="100vw"
    style={{ objectFit: 'cover' }}
    alt="Welcome to our site"
  />
</div>

記事リストサムネイル(遅延、中品質)

{posts.map(post => (
  <Image
    key={post.id}
    src={post.thumbnail}
    width={300}
    height={200}
    quality={75}
    alt={post.title}
  />
))}

フッターアイコン(遅延、低品質)

<Image
  src="/footer-icon.png"
  width={40}
  height={40}
  quality={60}
  alt="Footer icon"
/>

よくあるエラーと解決策

ここからは開発中によく遭遇するエラーと解決策です。

エラー1:Un-configured Host

最も頻繁に出るエラーです。

エラー

Error: Invalid src prop (https://example.com/image.jpg) on `next/image`, 
hostname "example.com" is not configured under images in your `next.config.js`

原因
外部 URL の画像を使っているのに、next.config.jsremotePatterns で許可していない。

解決
next.config.js にドメインを追加:

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/**',
      },
    ],
  },
}

注意

  1. 編集後は開発サーバー再起動必須(npm run dev し直し)
  2. hostname は完全一致のみ、ワイルドカード不可(サブドメインは個別に書くか、制限が緩い場合は要検討)
  3. 複数ドメイン使用時はオブジェクトを配列に追加していく

エラー2:レイアウトシフト / 高い CLS

症状
画像読み込み時に周りのコンテンツが押されて動く。

原因

  1. width / height がない
  2. fill を使っているのに親コンテナに高さがない

解決

ケース1:明確なサイズを指定

// ❌ ダメ
<Image src="/product.jpg" alt="Product" />

// ✅ OK
<Image src="/product.jpg" width={400} height={300} alt="Product" />

ケース2:親コンテナの高さ設定

// ❌ ダメ:親の高さ不明
<div style={{ position: 'relative', width: '100%' }}>
  <Image src="/hero.jpg" fill alt="Hero" />
</div>

// ✅ OK:親の高さあり
<div style={{ position: 'relative', width: '100%', height: '400px' }}>
  <Image src="/hero.jpg" fill alt="Hero" />
</div>

エラー3:画像がぼやける / サイズが大きすぎる

症状
モバイルで画像がぼやけたり、読み込みが遅い。

原因
sizes 属性がないため、Next.js がデフォルトの 100vw(全幅)として画像を生成している。実表示が画面半分なら、2倍の大きさの画像を読み込んでいることになる。

解決
実表示サイズに合わせて sizes を設定:

// 画面サイズによって幅が変わる場合
<Image
  src="/product.jpg"
  width={400}
  height={300}
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  alt="Product"
/>

サムネイルなど固定幅なら width/height だけで OK。

エラー4:廃止された API の使用

古いチュートリアルを見ると、廃止された書き方が載っていることがあります。

廃止1:domains 設定

// ❌ Next.js 14+ 非推奨
module.exports = {
  images: {
    domains: ['example.com'],
  },
}

// ✅ remotePatterns を推奨
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
      },
    ],
  },
}

廃止2:onLoadingComplete コールバック

// ❌ 廃止
<Image
  src="/image.jpg"
  ...
  onLoadingComplete={() => console.log('loaded')}
/>

// ✅ 改め onLoad
<Image
  src="/image.jpg"
  ...
  onLoad={() => console.log('loaded')}
/>

クイックチェックリスト

問題が起きたらチェックしましょう:

  1. ✅ リモート画像は remotePatterns に追加したか?
  2. next.config.js 変更後、サーバー再起動したか?
  3. widthheight(または fill + 親高さ)はあるか?
  4. fill 使用時、親は position: relative か?
  5. ✅ レスポンシブ画像に sizes は適切か?
  6. ✅ 廃止 API を使っていないか?

上級テクニックとベストプラクティス

さらに体験を向上させるテクニックです。

プレースホルダーで体感速度アップ

読み込み中に真っ白になるより、ぼやけた画像(ブラー)を表示する方がユーザー体験は良いです。

blur placeholder(ブラープレースホルダー)

import Image from 'next/image'
import heroImage from '/public/hero.jpg'

export default function Hero() {
  return (
    <Image
      src={heroImage}
      placeholder="blur"
      alt="Hero image"
    />
  )
}

ローカル画像を import した場合、Next.js が自動で低解像度の base64 画像を生成し、`placeholder=“blur”` で表示してくれます。

リモート画像の blur placeholder

リモート画像は手動で blurDataURL が必要です:

<Image
  src="https://example.com/image.jpg"
  width={800}
  height={600}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..."
  alt="Remote image"
/>

このオンラインツール かサーバー側の sharp ライブラリで生成できます。

CDN との連携

Next.js はデフォルトで自前の Image Optimization API を使いますが、Cloudinary や Uploadcare などの画像 CDN を使う場合はローダーを設定できます。

// next.config.js
module.exports = {
  images: {
    loader: 'cloudinary',
    path: 'https://res.cloudinary.com/your-cloud-name/',
  },
}

またはカスタムローダー関数:

// next.config.js
module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my-loader.js',
  },
}

// my-loader.js
export default function myLoader({ src, width, quality }) {
  return `https://cdn.example.com/${src}?w=${width}&q=${quality || 75}`
}

これで画像処理負荷を CDN にオフロードできます。高トラフィックサイト向け。

監視とデバッグ

Chrome DevTools

Network タブ → Img フィルタで確認:

  • ファイルサイズ
  • 読み込み時間
  • レスポンスヘッダー(フォーマット確認)

Image コンポーネントを使った画像は、URL 末尾に ?w=xxx&q=xxx と付き、最適化されていることが分かります。

Lighthouse テスト

Chrome DevTools → Lighthouse → Analyze page load で指標を確認:

  • LCP:理想 < 2.5秒
  • CLS:理想 < 0.1
  • Image 要素:最適化されていない画像を指摘してくれます

私は最適化のたびに Lighthouse を回しますが、通常 60点台から 90点以上に改善します。

継続監視

本番環境では、GSC(Google Search Console)や Vercel Analytics で Core Web Vitals を監視し、劣化を早期検知することをお勧めします。

結論

Next.js Image コンポーネントは、読み込み遅延、設定エラー、レイアウトシフトの3大問題を解決します。

正しく使えば以下が得られます:

  • 画像サイズ 60-80% 削減(WebP/AVIF)
  • LCP 2.5秒以下(priority の活用)
  • CLS ゼロ(サイズ/fill の適切な設定)

重要な5つの設定を覚えておいてください:

  1. リモート画像は remotePatterns 設定&再起動
  2. width/heightfill(+親高さ)を設定
  3. 首屏画像は priority、他はデフォルト(Lazy)
  4. レスポンシブ画像は sizes を設定
  5. 重要度で quality を調整(90/75/60)

今すぐあなたのプロジェクトの <img> タグを <Image> に置き換えてみてください。そして Lighthouse でテストしてみてください。少なくとも 20点はスコアアップするはずです。

Next.js Image コンポーネント最適化完全フロー

リモート画像設定からパフォーマンス最適化、レイアウトシフト回避までの完全ステップ

⏱️ Estimated time: 2 hr

  1. 1

    Step1: リモート画像ドメインの設定

    next.config.js で設定:
    • images.remotePatterns 配列を追加
    • protocol, hostname, pathname を設定
    • ワイルドカード対応

    例:
    images: {
    remotePatterns: [
    {
    protocol: 'https',
    hostname: 'example.com',
    pathname: '/images/**'
    }
    ]
    }

    注意:設定後は開発サーバーの再起動が必須
  2. 2

    Step2: img タグを Image コンポーネントに置換

    基本:
    • インポート:import Image from 'next/image'
    • width と height を設定(または fill)
    • alt テキスト追加(SEO必須)

    例:
    <Image
    src="/hero.jpg"
    width={800}
    height={600}
    alt="説明文"
    />
  3. 3

    Step3: レイアウトシフト(CLS)の処理

    方法1:固定サイズ設定
    • width と height を必ず設定
    • aspect-ratio で比率維持

    方法2:fill モード使用
    • 親コンテナに position: relative を設定
    • Image コンポーネントに fill 属性
    • 親コンテナに高さを設定

    方法3:プレースホルダー
    • blurDataURL:ブラー画像データ
    • placeholder="blur":ロード中に表示
  4. 4

    Step4: 読み込みパフォーマンス最適化

    首屏(ファーストビュー)重要画像:
    • priority 属性を追加
    • quality=90 に設定
    • viewport 内にあることを確認

    その他の画像:
    • デフォルトの遅延読み込み(設定不要)
    • quality=75(品質と容量のバランス)
    • sizes 属性でレスポンシブ対応

    サムネイル:
    • quality=60 で十分
    • 小さいサイズバージョンを使用
  5. 5

    Step5: レスポンシブ画像の設定

    sizes 属性を使用:
    • 画面サイズごとに必要な画像幅をブラウザに伝える
    • ブラウザが最適な画像を自動選択

    例:
    <Image
    src="/hero.jpg"
    width={1200}
    height={630}
    sizes="(max-width: 768px) 100vw, 50vw"
    alt="説明"
    />

    これでモバイルは全幅、デスクトップは50%幅を読み込む
  6. 6

    Step6: テストと検証

    パフォーマンステスト:
    • Lighthouse で LCP と CLS を測定
    • Network タブで画像ロード状況を確認
    • 画像フォーマット確認(WebP/AVIF)

    チェックリスト:
    • リモート画像のドメイン設定済みか
    • 全画像の width/height 設定済みか
    • 首屏画像に priority はあるか
    • CLS スコアは 0 に近いか
    • 画像サイズは 60% 以上削減されたか

FAQ

なぜリモート画像で 'Un-configured Host' エラーが出るのですか?
Next.js Image コンポーネントはセキュリティのため、許可されたドメインの画像のみを最適化します。next.config.js の images.remotePatterns に、protocol、hostname、pathname を含むドメイン設定を追加し、サーバーを再起動してください。
Image コンポーネントに width と height は必須ですか?
はい、必須です。これはレイアウトシフト(CLS)を防ぐためです。固定サイズにしたくない場合は、fill 属性を使い、親コンテナの高さに合わせて調整するか、aspect-ratio を使用してください。
画像読み込み時のレイアウトズレ(CLS)を防ぐには?
1) width/height を設定、2) fill と親コンテナの高さ設定、3) placeholder="blur" の使用、4) aspect-ratio の維持。重要なのは、画像読み込み前にコンテナサイズを確定させることです。
priority 属性はいつ使うべきですか?
priority は首屏(Above the fold)に見える重要画像に使います。これにより遅延読み込みが無効化され、LCP が向上します。Hero 画像やロゴなどに使いますが、使いすぎには注意してください。
Image コンポーネントは自動で画像フォーマット変換をしますか?
はい。ブラウザの対応状況に応じて、自動的に WebP や AVIF に変換します。これにより通常 60-80% の容量削減と読み込み速度向上が実現します。
sizes 属性の役割は何ですか?
sizes は、画面サイズごとに画像がどのくらいの幅で表示されるかをブラウザに伝えます。これによりブラウザは srcset から最適なサイズの画像を選択してダウンロードするため、モバイルでの過剰なデータ通信を防げます。
画質(quality)はどう設定すべきですか?
重要画像は 90、通常画像は 75(デフォルト)、サムネイルは 60 が目安です。画質とファイルサイズはトレードオフなので、用途に応じて調整してください。

9 min read · 公開日: 2025年12月19日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事