各デバイスに適した画像サイズを提供することは、最も効果の高いパフォーマンス最適化の一つです。 375px のスマートフォン画面で 3000px のヒーロー画像は帯域幅を無駄にし、LCP を遅くします。srcset と sizes 属性は、JavaScript なしのネイティブ HTML で この問題を解決します。
問題:すべてのデバイスに一つの画像
レスポンシブ画像なしでは、通常は最大の画像を提供して CSS で縮小します。視覚的には機能しますが 帯域幅を無駄にします。小さな画面では 60KB のバージョンが同じに見えるにもかかわらず、 400KB のデスクトップ画像をモバイルでも読み込むことになります。
srcset:画像バリアントの定義
srcset 属性は利用可能な画像ファイルとその幅をリストします:
<img
src="hero-800.webp"
srcset="hero-400.webp 400w,
hero-800.webp 800w,
hero-1600.webp 1600w"
alt="ヒーロー画像"
/>
ブラウザはディスクリプタ(400w = 400ピクセル幅)と現在のビューポート幅を 読み取り、最適なファイルを選択します。sizes 属性なしでは、画像が 100vw 幅 だと仮定します — 通常は間違った仮定です。
sizes:ブラウザに表示幅を伝える
sizes 属性は、異なるビューポートのブレークポイントで画像がどのくらいの 幅で表示されるかを記述します:
<img
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1600.webp 1600w"
sizes="(max-width: 640px) 100vw,
(max-width: 1024px) 50vw,
800px"
alt="ヒーロー画像"
/>
ブラウザに伝えます:モバイル(<640px)では全幅、タブレットではビューポートの 50%、 デスクトップでは常に 800px。ブラウザはこれをデバイスピクセル比と組み合わせて最適な ファイルを選択します。
デバイスピクセル比
Retina ディスプレイはデバイスピクセル比(DPR)が 2 または 3 で、鮮明にレンダリングするには 2〜3倍多くのピクセルが必要です。sizes="100vw" を持つ 375px Retina ディスプレイの ブラウザは実際に 800w 画像をリクエストします(375 × 2 DPR ≈ 750px → 最も近いバリアントは 800w)。 十分なバリアントを提供すれば自動的に処理されます。
picture 要素:アートディレクション
モバイルで単に小さいだけでなく、まったく異なるクロップを提供したい場合は <picture> を使います:
<picture>
<source media="(max-width: 640px)" srcset="hero-square-400.webp" />
<source media="(min-width: 641px)" srcset="hero-wide-1600.webp" />
<img src="hero-wide-1600.webp" alt="ヒーロー画像" />
</picture>
picture で最新フォーマットを配信
<picture> を使って対応ブラウザには AVIF を、フォールバックとして WebP と JPEG を提供します:
<picture>
<source type="image/avif" srcset="hero.avif" />
<source type="image/webp" srcset="hero.webp" />
<img src="hero.jpg" alt="ヒーロー画像" />
</picture>
Next.js:自動 srcset 生成
Next.js の <Image> コンポーネントは deviceSizes と imageSizes の設定に基づいて srcset を自動生成します。sizes プロップは HTML の sizes 属性に直接マッピングされます:
<Image
src="/hero.jpg"
width={1600}
height={900}
sizes="(max-width: 640px) 100vw, 800px"
alt="ヒーロー"
/>
sizes プロップなしでは Next.js は 100vw をデフォルトにします — 不必要に大きな画像のロードを避けるために正しく設定してください。詳しいトレードオフ分析は next/image ガイドを参照してください。
クイックチェックリスト
- 常に
sizesを設定 —100vwのデフォルトに頼らない - 画像ごとに最低 3 つの幅バリアントを提供(小・中・大)
- Retina サポートのための 2× バリアントを含める
- 折り返し以下の画像は
loading="lazy"で遅延読み込み - LCP 画像は
<link rel='preload'>でプリロード
画像を WebP に手動変換するには Picovert の PNG to WebP コンバーターを使用してください。