JA EN

レスポンシブ画像の実装ガイド - srcset, sizes, picture 要素の完全解説

· 約 11 分で読めます

レスポンシブ画像が必要な理由

現代の Web では、同じページが 320px 幅のスマートフォンから 3,840 px 幅の 4K モニターまで、多様なデバイスで閲覧されます。すべてのデバイスに同じ画像を配信すると、モバイルユーザーには不必要に大きなファイルをダウンロードさせ、高解像度ディスプレイのユーザーにはぼやけた画像を表示することになります。どちらのケースもユーザー体験を損ない、ビジネス指標に悪影響を与えます。

具体的な数値で考えてみましょう。幅 1,920 px の画像は約 300KB ですが、モバイルで表示する際に必要なのは幅 640px (約 50KB) 程度です。年間 100 万 PV のサイトでモバイルユーザーが 60% だとすると、レスポンシブ画像を実装するだけで月間約 150GB のデータ転送量を削減できます。これは CDN コストの削減だけでなく、ユーザーの通信量節約にも直結します。

Google の Core Web Vitals においても、画像の最適化は LCP (Largest Contentful Paint) スコアに大きく影響します。ファーストビューに表示される画像が適切なサイズで配信されていないと、LCP が悪化し検索順位に影響する可能性があります。レスポンシブ画像は単なる最適化テクニックではなく、現代の Web 開発における必須要件です。

srcset 属性による解像度の切り替え

srcset 属性は、ブラウザに複数の画像候補を提示し、デバイスの条件に応じて最適なものを選択させる仕組みです。記述方法には「幅記述子 (w)」と「ピクセル密度記述子 (x)」の 2 種類があります。

幅記述子を使用する場合、各画像の実際のピクセル幅を指定します:

ピクセル密度記述子は、Retina ディスプレイ対応に特化した記法です:

幅記述子と sizes 属性の組み合わせが推奨される理由は、ブラウザがビューポート幅とデバイスピクセル比の両方を考慮して最適な画像を選択できるためです。例えば、375px 幅の iPhone (2x) で sizes="100vw" の画像を表示する場合、ブラウザは 750w 以上の画像を選択します。これにより、1 つの srcset 宣言で解像度とビューポートサイズの両方に対応できます。

sizes 属性の正しい書き方

sizes 属性は、画像が各ブレークポイントでどのくらいの幅で表示されるかをブラウザに伝えます。ブラウザはこの情報と srcset の候補リストを組み合わせて、ダウンロードすべき画像を決定します。重要なのは、sizes はレイアウトが確定する前 (CSS の読み込み前) にブラウザが参照するため、CSS のブレークポイントと一致させる必要があるという点です。

sizes の構文はメディア条件とスロット幅のペアで構成されます:

この例では、ビューポート幅 600px 以下で画像幅 100vw、601px〜1,200 px で 50vw、それ以上で 33vw と宣言しています。ブラウザは最初にマッチした条件のスロット幅を使用し、デバイスピクセル比を掛けて必要な画像幅を算出します。

よくある間違いとして、sizes に固定ピクセル値を使用するケースがあります。sizes="300px" と書くと、すべてのビューポートで 300px 幅として計算されるため、レスポンシブの意味がなくなります。代わりに calc() を活用して sizes="(max-width: 768px) calc(100vw - 32px), calc(50vw - 48px)" のようにパディングを考慮した正確な値を指定すると、ブラウザの画像選択精度が向上します。

picture 要素によるアートディレクション

<picture> 要素は、srcset だけでは実現できない「アートディレクション」を可能にします。アートディレクションとは、画面サイズに応じて画像の構図やクロップを変更することです。例えば、デスクトップでは横長のパノラマ写真を表示し、モバイルでは被写体を中心にクロップした正方形の画像を表示するといった制御が可能です。

<picture> 要素の基本構造:

<source> 要素の media 属性はメディアクエリを受け取り、条件に一致する最初の <source> が使用されます。srcset と異なり、<picture> ではブラウザに選択の余地がなく、条件に一致した <source> が強制的に使用されます。これがアートディレクションに適している理由です。

さらに、<picture> は画像フォーマットの出し分けにも使用できます。WebP や AVIF に対応したブラウザには次世代フォーマットを、非対応ブラウザには JPEG を配信する構成が一般的です。type 属性で MIME タイプを指定することで、ブラウザは対応するフォーマットを自動的に選択します。

実装のベストプラクティスとパフォーマンス最適化

レスポンシブ画像を実装する際の具体的なベストプラクティスを紹介します。まず、画像のブレークポイント (生成するサイズのバリエーション) は 3〜5 段階が適切です。あまりに多くのバリエーションを用意すると CDN のキャッシュ効率が低下し、少なすぎると最適化の効果が薄れます。

推奨するサイズバリエーション:

LCP 対象の画像 (ファーストビューのヒーロー画像など) には fetchpriority="high" を付与し、ブラウザに優先的にダウンロードさせます。逆に、ファーストビュー外の画像には loading="lazy" を設定して遅延読み込みを有効にします。この 2 つの属性を適切に使い分けることで、初期表示速度を最大化できます。

widthheight 属性を必ず指定し、ブラウザがレイアウトシフト (CLS) を防止できるようにします。アスペクト比が異なる画像を <picture> で出し分ける場合は、CSS の aspect-ratio プロパティと組み合わせて CLS を防ぎます。

ビルドパイプラインでの自動生成

レスポンシブ画像の複数サイズを手動で生成するのは非現実的です。ビルドパイプラインに画像処理を組み込み、自動的にリサイズ・フォーマット変換・最適化を行う仕組みを構築しましょう。

Node.js 環境では sharp ライブラリが最も高速で信頼性の高い選択肢です。以下のようなスクリプトで複数サイズを一括生成できます:

Next.js の next/image コンポーネントや Gatsby の gatsby-plugin-image は、ビルド時に自動的にレスポンシブ画像を生成し、適切な srcsetsizes を出力します。フレームワークの機能を活用することで、手動での HTML 記述を最小限に抑えられます。

CDN レベルでの画像変換サービス (Cloudflare Images、imgix、Cloudinary など) を利用する方法もあります。URL パラメータでサイズやフォーマットを指定するだけで、オリジン画像から動的にリサイズされた画像が配信されます。ビルド時の処理が不要になる反面、リクエストごとに変換コストが発生する (キャッシュミス時) ため、トラフィック量とコストのバランスを考慮する必要があります。

関連記事

画像の遅延読み込み実装ガイド - loading=lazy と IntersectionObserver の使い分け

Web ページの初期表示速度を改善する画像遅延読み込みの実装方法を、ネイティブ API と JavaScript の両アプローチで解説します。

Web 用画像のファイルサイズ最適化戦略 - 品質を保ちながら軽量化する技術

Web パフォーマンスを最大化するための画像ファイルサイズ最適化手法を、フォーマット選択からメタデータ除去まで体系的に解説します。

WebP のメリットと対応状況 - 次世代画像フォーマットの実力

Google が開発した WebP フォーマットのメリット、デメリット、ブラウザ対応状況を解説。JPEG や PNG からの移行判断に必要な情報をまとめます。

アートディレクションでデバイス別に画像を出し分ける - picture 要素と media 属性の実践

レスポンシブ画像のアートディレクション手法を解説。picture 要素と media 属性でデバイスごとに最適な構図の画像を配信し、ユーザー体験とパフォーマンスを両立させます。

Retina ディスプレイ対応画像の作り方 - 高 DPI 環境での鮮明な表示を実現する

Retina や高 DPI ディスプレイで画像がぼやける原因と対策を解説。srcset 属性、image-set()、SVG 活用、最適な書き出し設定まで実践的に紹介します。

Web サイトの画像パフォーマンス監査 - Core Web Vitals 改善の実践ガイド

Web サイトの画像がパフォーマンスに与える影響を監査する方法を解説。LCP 改善、CLS 防止、転送量削減の具体的な手法を紹介します。

関連用語