Webページの表示速度を左右する最大の要因は画像です。HTTP Archiveのデータによると、Webページの総転送量のうち画像が占める割合は約40〜50%に達します(出典: HTTP Archive)。Nuxt 3で構築したサイトでこの課題に対処するには、公式モジュール @nuxt/image が最も効率的な選択肢です。

@nuxt/image とは

@nuxt/image は、Nuxt 3公式の画像最適化モジュールです。HTMLの <img> タグや <picture> タグを置き換える <NuxtImg> / <NuxtPicture> コンポーネントを提供し、以下の処理を自動化します。

  • フォーマット変換: WebP・AVIFなど次世代フォーマットへの自動変換
  • レスポンシブ対応: 画面サイズに応じた srcsetsizes の自動生成
  • 遅延読み込み: loading="lazy" によるビューポート外画像の遅延ロード
  • プリロード制御: LCP画像への fetchpriority="high" 付与とプリロード設定
  • プロバイダー連携: IPX(セルフホスト)、Cloudinary、imgix、Vercelなど20以上のサービスに対応

インストールと初期設定

パッケージの追加

# 自動セットアップ(推奨)
npx nuxt module add image

# 手動インストール
npm install @nuxt/image

手動インストールの場合は nuxt.config.ts にモジュールを登録します。

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/image'],
  image: {
    // 画像オプション
  }
})

基本的な設定例

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/image'],
  image: {
    quality: 80,
    format: ['webp'],
    screens: {
      xs: 320,
      sm: 640,
      md: 768,
      lg: 1024,
      xl: 1280,
      '2xl': 1536,
    },
    domains: ['example.com'],
  }
})

quality はデフォルト80で、全画像に適用される品質値です。format<NuxtPicture> 使用時の優先フォーマットを配列で指定します。screens はTailwind CSSと同じブレークポイント命名規則に準拠しており、sizes 属性で sm:50vw のように参照できます。

NuxtImg と NuxtPicture の使い分け

@nuxt/image は2つのコンポーネントを提供しています。

NuxtImg

HTMLの <img> タグを置き換えるコンポーネントです。単一フォーマットの画像配信に適しています。

<template>
  <NuxtImg
    src="/images/hero.jpg"
    alt="ヒーロー画像"
    width="1200"
    height="630"
    sizes="100vw md:80vw lg:1200px"
    quality="80"
    format="webp"
    loading="lazy"
  />
</template>

出力されるHTMLには、指定した sizes に応じた srcset が自動生成されます。

NuxtPicture

HTMLの <picture> タグを生成し、複数フォーマットの出し分けに対応します。ブラウザのサポート状況に応じてAVIF → WebP → JPEGの順にフォールバックさせたい場合に使用します。

<template>
  <NuxtPicture
    src="/images/product.jpg"
    alt="製品写真"
    width="800"
    height="600"
    sizes="100vw sm:50vw lg:400px"
    format="avif,webp"
  />
</template>

選択基準の早見表

条件推奨コンポーネント
WebPのみで配信<NuxtImg format="webp">
AVIF + WebP + JPEGのフォールバック<NuxtPicture>
OGP画像やSNSシェア用<NuxtImg><picture> はOGPクローラーに未対応の場合あり)
art direction(画面幅で異なる画像)<NuxtPicture> + <source> のカスタム実装

主要プロパティの効果と設定方法

sizes ― レスポンシブ srcset の自動生成

sizes 属性は、ブレークポイントごとの表示幅を指定する最も重要なプロパティです。

<NuxtImg
  src="/images/banner.jpg"
  alt="バナー"
  sizes="100vw sm:50vw md:33vw lg:400px"
/>

この指定により、各ブレークポイントに対応する幅の画像が srcset として生成されます。ブラウザは画面サイズとDevice Pixel Ratio(DPR)をもとに最適な画像を選択します。

densities ― Retina対応

densities 属性でDPR倍率を指定できます。デフォルト値は [1, 2] です。

<!-- 1xと2xの画像を生成 -->
<NuxtImg
  src="/images/icon.png"
  alt="アイコン"
  width="64"
  height="64"
  densities="x1 x2"
/>

固定サイズのアイコンやアバターには densities を、フルードレイアウトの画像には sizes を使用するのが適切です。

quality ― 圧縮品質

0〜100の数値で画像品質を指定します。ファイルサイズと画質のトレードオフを意識した設定が重要です。

用途推奨quality値備考
ヒーロー画像・メインビジュアル80〜90LCPに直結するため画質優先
商品画像・コンテンツ画像70〜80バランス重視
サムネイル・一覧画像50〜70ファイルサイズ削減優先
背景・装飾画像40〜60視認品質を維持しつつ軽量化

preload と fetchpriority ― LCP画像の優先読み込み

ファーストビューに表示されるLCP(Largest Contentful Paint)画像には、preload 属性を付与します。

<NuxtImg
  src="/images/hero.jpg"
  alt="メインビジュアル"
  sizes="100vw"
  preload
/>

preload を指定すると、<head> 内に以下のようなタグが自動挿入されます。

<link rel="preload" as="image" href="/_ipx/w_1280/images/hero.jpg" imagesizes="100vw" imagesrcset="..." fetchpriority="high">

LCP画像には loading="lazy" を付けない のが鉄則です。preload 指定時は自動的に遅延読み込みが無効化されます。

loading ― 遅延読み込み

ファーストビュー外の画像には loading="lazy" を指定します。

<NuxtImg
  src="/images/content.jpg"
  alt="コンテンツ画像"
  loading="lazy"
  sizes="100vw md:80vw"
/>

loading 属性を省略した場合、ブラウザのデフォルト動作(eager)になります。ファーストビューのLCP画像以外は原則 lazy を指定してください。

placeholder ― 読み込み中の表示

画像の読み込み完了までプレースホルダーを表示できます。CLS(Cumulative Layout Shift)の防止にも寄与します。

<!-- 自動生成のぼかしプレースホルダー -->
<NuxtImg
  src="/images/photo.jpg"
  alt="写真"
  placeholder
  width="800"
  height="600"
/>

<!-- サイズとぼかし量を指定 -->
<NuxtImg
  src="/images/photo.jpg"
  alt="写真"
  :placeholder="[50, 25, 75, 5]"
  width="800"
  height="600"
/>

引数の順序は [幅, 高さ, 品質, ぼかし量] です。

画像プロバイダーの選び方

@nuxt/image は20以上のプロバイダーに対応しています。代表的なプロバイダーの特徴を比較します。

プロバイダーホスティング料金目安WebP/AVIFCDN適用場面
IPXセルフホスト無料(サーバーコスト)対応自前で用意小〜中規模サイト、SSR環境
Cloudinaryクラウド無料枠あり(月25クレジット)対応内蔵画像加工が多いECサイト
imgixクラウド月$5〜対応内蔵メディアサイト、高トラフィック
VercelVercel専用Vercel料金に含む対応Vercel EdgeVercelデプロイ時
NetlifyNetlify専用Netlify料金に含むWebPのみNetlify EdgeNetlifyデプロイ時

IPX(デフォルトプロバイダー)

IPXはNuxt Imageに組み込まれたセルフホスト型の画像処理エンジンで、内部的に Sharp(libvips)を使用しています。外部サービスへの依存がなく、サーバー上で画像のリサイズ・フォーマット変換・品質調整を行います。

// nuxt.config.ts - IPXの追加設定例
export default defineNuxtConfig({
  image: {
    ipx: {
      modifiers: {
        quality: 80,
        format: 'webp',
      }
    }
  }
})

Cloudinaryプロバイダーの設定

// nuxt.config.ts
export default defineNuxtConfig({
  image: {
    provider: 'cloudinary',
    cloudinary: {
      baseURL: 'https://res.cloudinary.com/your-cloud-name/image/upload'
    }
  }
})
<template>
  <NuxtImg
    provider="cloudinary"
    src="/v1234567890/sample.jpg"
    alt="Cloudinary画像"
    width="600"
    height="400"
  />
</template>

プロバイダーの混在利用

1つのプロジェクト内で複数のプロバイダーを使い分けることも可能です。

<template>
  <!-- デフォルトIPXで処理 -->
  <NuxtImg src="/images/local.jpg" alt="ローカル画像" />

  <!-- Cloudinaryで処理 -->
  <NuxtImg provider="cloudinary" src="/remote/photo.jpg" alt="外部画像" />
</template>

Core Web Vitalsを改善する実装テクニック

GoogleのCore Web Vitalsは検索順位に影響するランキングシグナルです。画像最適化はLCPとCLSの改善に直結します。

LCP(Largest Contentful Paint)の改善

LCPのスコアは「良好」が2.5秒以内、「要改善」が2.5〜4.0秒、「不良」が4.0秒超と定義されています(出典: web.dev)。

画像がLCP要素になるケースは非常に多く、改善には以下の戦略が有効です。

<!-- LCP画像のベストプラクティス -->
<template>
  <NuxtImg
    src="/images/hero.jpg"
    alt="メインビジュアル"
    width="1280"
    height="720"
    sizes="100vw lg:1280px"
    quality="85"
    format="webp"
    preload
    :densities="['x1', 'x2']"
  />
</template>

LCP改善のチェックリスト:

  • preload 属性でプリロードを有効化する
  • loading="lazy" を付けない(LCP画像を遅延させると逆効果)
  • width / height を明示してレイアウトシフトを防ぐ
  • sizes で適切な画像サイズを指定し、過大な画像の転送を回避する
  • format="webp" または <NuxtPicture> でファイルサイズを削減する

CLS(Cumulative Layout Shift)の防止

CLSは「良好」が0.1以下です(出典: web.dev)。画像読み込み時のレイアウトシフトを防ぐには、画像のアスペクト比を事前に確保する必要があります。

<!-- width/height でアスペクト比を確定 -->
<NuxtImg
  src="/images/card.jpg"
  alt="カード画像"
  width="400"
  height="300"
  loading="lazy"
  class="w-full h-auto"
/>

widthheight を指定することで、ブラウザはCSSの aspect-ratio を自動計算し、画像読み込み前にスペースを確保します。CSSで width: 100%; height: auto; を併用するのが定番パターンです。

実装前後のスコア比較例

以下は、一般的なNuxtサイトで@nuxt/imageを導入した際の改善効果の目安です。

指標導入前(目安)導入後(目安)改善率
LCP4.0〜6.0秒1.5〜2.5秒40〜60%
CLS0.15〜0.300.01〜0.0580〜90%
画像転送量3〜5MB0.8〜1.5MB60〜70%

※ 値はサイト構成・画像枚数・サーバー環境により変動します。

レスポンシブ画像のパターン別実装

パターン1: フルブリード画像(画面幅いっぱい)

<NuxtImg
  src="/images/wide-banner.jpg"
  alt="全幅バナー"
  sizes="100vw"
  quality="80"
  loading="lazy"
/>

パターン2: コンテナ幅に制限された画像

<NuxtImg
  src="/images/article.jpg"
  alt="記事画像"
  sizes="100vw md:80vw lg:720px"
  quality="75"
  loading="lazy"
/>

パターン3: カード型レイアウト(グリッド)

<template>
  <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
    <div v-for="item in items" :key="item.id">
      <NuxtImg
        :src="item.image"
        :alt="item.title"
        width="400"
        height="300"
        sizes="100vw sm:50vw lg:33vw"
        quality="70"
        loading="lazy"
      />
    </div>
  </div>
</template>

パターン4: AVIF/WebP/JPEGの段階的フォールバック

<NuxtPicture
  src="/images/photo.jpg"
  alt="風景写真"
  sizes="100vw md:80vw lg:960px"
  format="avif,webp"
  quality="80"
  loading="lazy"
/>

<NuxtPicture>format に指定した順序で <source> 要素を生成し、最後に元のフォーマット(JPEG等)をフォールバックとして配置します。

SSR・SSG・SPAモードごとの注意点

SSR(サーバーサイドレンダリング)

SSRモードではIPXがサーバー上でリクエストのたびに画像を処理します。初回リクエスト時に変換が行われ、以降はキャッシュから配信されます。

  • IPXのサーバーサイド処理が利用可能
  • preload タグが初期HTMLに含まれるため、LCPの改善効果が最大化される
  • サーバーのCPU・メモリリソースを消費する点に注意

SSG(静的サイト生成)

SSGモードではビルド時に画像が処理・生成されます。デフォルトプロバイダーは ipxStatic に切り替わります。

// nuxt.config.ts - SSG向け設定
export default defineNuxtConfig({
  image: {
    // SSG時は自動的にipxStaticが使用される
    // staticFilenameでファイル命名規則を指定可能
    staticFilename: '[publicPath]/images/[name]-[hash].[ext]',
  }
})
  • ビルド時に全画像バリアントが生成されるため、デプロイ後のサーバー負荷はゼロ
  • 画像の追加・変更時は再ビルドが必要
  • 生成される画像ファイル数が多い場合、ビルド時間が延びる

SPA(シングルページアプリケーション)

SPAモード(ssr: false)ではサーバーサイド処理が使えないため、制約があります。

  • IPXのサーバー機能が利用不可
  • Cloudinaryやimgixなどのクラウドプロバイダーの利用が推奨される
  • preload タグは初期HTMLに含まれないため、LCPへの効果が限定的

外部ドメインの画像を最適化する

外部サイトの画像を @nuxt/image で処理するには、domains 設定でホワイトリスト登録が必要です。

// nuxt.config.ts
export default defineNuxtConfig({
  image: {
    domains: [
      'images.unsplash.com',
      'cdn.example.com',
    ],
  }
})
<NuxtImg
  src="https://images.unsplash.com/photo-xxxxx"
  alt="Unsplash画像"
  width="800"
  height="600"
  loading="lazy"
/>

IPXプロバイダー使用時は、リモートの画像がサーバー経由でフェッチ・変換されます。レイテンシを抑えるにはCDNの併用を検討してください。

presetsで画像設定を統一する

プロジェクト全体で画像設定を統一したい場合、presets が有用です。

// nuxt.config.ts
export default defineNuxtConfig({
  image: {
    presets: {
      thumbnail: {
        modifiers: {
          width: 200,
          height: 200,
          fit: 'cover',
          quality: 60,
          format: 'webp',
        }
      },
      hero: {
        modifiers: {
          width: 1280,
          height: 720,
          fit: 'cover',
          quality: 85,
          format: 'webp',
        }
      },
    }
  }
})
<template>
  <!-- presetsを適用 -->
  <NuxtImg preset="thumbnail" src="/images/avatar.jpg" alt="アバター" />
  <NuxtImg preset="hero" src="/images/hero.jpg" alt="ヒーロー" />
</template>

preset を使うことで、コンポーネント側のコードを簡潔に保ちつつ、設定変更を nuxt.config.ts に集約できます。

よくあるトラブルと解決策

画像が表示されない

原因1: パスの指定ミス <NuxtImg>srcpublic/ ディレクトリからの絶対パスで指定します。assets/ ディレクトリの画像には対応していません。

<!-- NG: assets内の画像 -->
<NuxtImg src="~/assets/images/photo.jpg" />

<!-- OK: public内の画像 -->
<NuxtImg src="/images/photo.jpg" />

原因2: 外部ドメイン未登録 外部URLの画像を使う場合は domains への登録が必要です。

SPAモードでIPXが動作しない

ssr: false の環境ではIPXのサーバー処理が使えません。Cloudinaryやimgixなどのクラウドプロバイダーへ切り替えてください。

ビルド時に画像生成が遅い

SSGで大量の画像バリアントを生成する場合、ビルド時間が増大します。以下の対策が有効です。

  • screens のブレークポイント数を必要最小限に絞る
  • densities[1, 2] に限定する([1, 1.5, 2, 3] のような過剰設定を避ける)
  • 画像枚数が多い場合はCloudinaryなどのクラウドプロバイダーで処理をオフロードする

placeholder が表示されない

placeholder 属性はIPXプロバイダーのSSR/SSGモードで動作します。SPAモードやクラウドプロバイダーでは使用できない場合があります。

まとめ

@nuxt/image は、<NuxtImg><NuxtPicture> の2つのコンポーネントで画像最適化の大部分を自動化するNuxt 3公式モジュールです。sizes によるレスポンシブ対応、preloadfetchpriority によるLCP改善、width / height 指定によるCLS防止など、Core Web Vitalsに直結する改善を少ないコード変更で実現できます。

IPXをはじめとする20以上のプロバイダーに対応しており、セルフホストからクラウドサービスまでプロジェクトの規模や要件に応じた選択が可能です。

公式ドキュメント: https://image.nuxt.com/