レスポンシブ画像をプリロードする

レスポンシブ画像をプリロードすると、ブラウザが img タグをレンダリングする前に srcset から正しい画像を識別できるようになるため、画像の読み込み速度が大幅に向上します。

レスポンシブ画像の概要

対応ブラウザ

  • 73
  • 79
  • 78
  • 17.2

幅 300 ピクセルの画面でウェブを閲覧していて、そのページから幅 1, 500 ピクセルの画像がリクエストされたとします。その画面では解像度を上げられないため、多くのモバイルデータが無駄になってしまいます。ブラウザは、画面サイズより少し幅大きい画像(325 ピクセルなど)を取得するのが理想的です。これにより、データを浪費することなく高解像度の画像が保証され、画像の読み込みが速くなります。

レスポンシブ画像を使用すると、ブラウザはデバイスごとに異なる画像リソースを取得できます。画像 CDN を使用しない場合は、画像ごとに複数のディメンションを保存して、srcset 属性で指定します。w 値はブラウザに対して各バージョンの幅を伝えるため、任意のデバイスに適したバージョンを選択できます。

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

プリロードの概要

対応ブラウザ

  • 50
  • 79 以下
  • 85
  • 11.1

ソース

プリロードを使用すると、重要なリソースを HTML で検出される前にできるだけ早く読み込むようにブラウザに伝えることができます。これは、スタイルシートに含まれるフォント、背景画像、スクリプトから読み込まれたリソースなど、すぐには検出できないリソースの場合に特に便利です。

<link rel="preload" as="image" href="important.png">

imagesrcsetimagesizes

<link> 要素は、imagesrcset 属性と imagesizes 属性を使用してレスポンシブ画像をプリロードします。<img> 要素では srcset 構文と sizes 構文を使用して、<link rel="preload"> とともに使用します。

たとえば、次のように指定したレスポンシブ画像をプリロードしたい場合は、次のようにします。

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

これを行うには、HTML の <head> に次の行を追加します。

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">

これにより、srcsetsizes が使用するのと同じリソース選択ロジックを使用してリクエストが開始されます。

ユースケース

レスポンシブ画像をプリロードするユースケースには、次のようなものがあります。

動的に挿入されたレスポンシブ画像をプリロードする

スライドショーの一部としてヒーロー画像を動的に読み込み、どの画像が最初に表示されるかがわかっているとします。スライドショーのスクリプトによる読み込みを待たずに、できるだけ早く画像を表示することをおすすめします。

この問題は、動的に読み込まれる画像ギャラリーを使用するウェブサイトで検査できます。

  1. このスライドショーのデモを新しいタブで開きます。
  2. Control+Shift+J(Mac の場合は Command+Option+J)を押して DevTools を開きます。
  3. [Network] タブをクリックします。
  4. [Throttling] プルダウン リストで [Fast 3G] を選択します。
  5. [キャッシュを無効にする] チェックボックスをオフにします。
  6. ページを再読み込みする。
Chrome DevTools の [Network] パネルのスクリーンショット。
プリロードしない場合は、ブラウザでスクリプトの実行が完了すると画像の読み込みが開始されます。最初のイメージでは、この遅延は不要です。

ここで preload を使用すると、画像の読み込みを事前に開始できるため、ブラウザで画像を表示する必要があるときに、表示準備が整います。

Chrome DevTools の [Network] パネルのスクリーンショット。
最初の画像をプリロードすると、スクリプトと同時に読み込みを開始できます。

プリロードによる違いを確認するには、最初の例の手順に沿って、動的に読み込まれる同じ画像ギャラリーで、最初の画像をプリロードした状態で調べます。

イメージセットを使用して背景画像をプリロードする

画面密度ごとに異なる背景画像がある場合は、CSS で image-set 構文を使用して指定できます。これにより、ブラウザは画面の DPR に基づいて、表示するビューを選択できます。

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

CSS の背景画像の問題は、ブラウザがページの <head> 内のすべての CSS をダウンロードして処理した後にのみ、背景画像を検出することです。

この問題は、レスポンシブな背景画像を含むサンプル ウェブサイトで確認できます。

Chrome DevTools の [Network] パネルのスクリーンショット。
この例では、CSS のダウンロードが完了するまで画像のダウンロードは開始されないため、画像が表示されるまでに不要な遅延が発生しています。

レスポンシブ画像のプリロードを使用すると、それらの画像をより迅速に読み込むことができます。

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">

href 属性を省略すると、<link> 要素の imagesrcset はサポートしていないが、CSS の image-set はサポートしているブラウザが正しいソースをダウンロードできるようになります。ただし、この場合はプリロードのメリットが得られません。

前の例が、プリロードされたレスポンシブ背景画像に対してどのように動作するかは、レスポンシブな背景のプリロードのデモで確認できます。

Chrome DevTools の [Network] パネルのスクリーンショット。
ここでは、画像と CSS が同時にダウンロードを開始し、画像の読み込みが速くなります。

レスポンシブ画像のプリロードの実用的効果

理論上は、レスポンシブ画像をプリロードすると高速化されますが、実際にはどのような処理が行われるのでしょうか。

そこで、デモ PWA ショップの 2 つのコピーを作成しました。画像をプリロードしないものと、画像の一部をプリロードするものです。JavaScript を使用して画像の遅延読み込みを行うため、最初のビューポートに表示される画像をプリロードすることでメリットが得られる可能性があります。

これにより、プリロードなしイメージ プリロードで次の結果が生成されました。

  • [レンダリングを開始] に変更はありません。
  • Speed Index がわずかに改善されました(273 ミリ秒。画像はより速く到着するため、ピクセル領域の大部分を占有しません)。
  • Last Painted Hero が 1.2 秒と大幅に改善されました。
プリロードされた画像が約 1.5 秒速く表示されることを示す WebPageTest のフィルムストリップの比較のスクリーンショット。
プリロードすると、画像が表示されるまでの時間が大幅に短縮され、ユーザー エクスペリエンスが大幅に向上します。

プリロードと <picture>

ウェブ パフォーマンス ワーキング グループは、srcsetsizes に相当するプリロードの追加について議論していますが、「アート ディレクション」のユースケースを処理する <picture> 要素は追加していません。

<picture> のプリロードに関して、解決すべき技術的な問題はまだ数多くありますが、それまでの間、次の回避策があります。

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

<picture> 要素の画像ソース選択ロジックは、<source> 要素の media 属性を順番に調べ、最初に一致するリソースを見つけて、添付されたリソースを使用します。

レスポンシブ プリロードには「順序」や「最初の一致」の概念がないため、ブレークポイントを次のように変換する必要があります。

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">

プリロードと type

<picture> 要素は最初の type での一致もサポートしているため、さまざまな画像形式を指定して、ブラウザがサポートする最初の画像形式を選択できます。このユースケースはプリロードではサポートされていません。

タイプのマッチングを使用しているサイトでは、プリロードを回避し、代わりにプリロード スキャナ<picture> 要素と <source> 要素から画像を取得することをおすすめします。いずれにしても、これは特に優先度ヒントを使用して適切な画像を優先する場合におすすめの方法です。

Largest Contentful Paint(LCP)への影響

画像は Largest Contentful Paint(LCP)の候補になる可能性があるため、プリロードすることでウェブサイトの LCP を改善できます。

プリロードする画像がレスポンシブかどうかにかかわらず、最初のマークアップ ペイロードで画像リソースを検出できない場合、プリロードが最適に機能します。また、完全なマークアップをサーバーから送信するサイトよりも、クライアント側でマークアップをレンダリングするサイトの LCP も大きく向上します。