ウェブ向けのブラウザレベルの画像遅延読み込み

対応ブラウザ

  • 77
  • 79
  • 75
  • 15.4

loading 属性を使用すると、カスタムの遅延読み込みコードを記述したり、別の JavaScript ライブラリを使用したりすることなく、画像の遅延読み込みを行うことができます。次のデモをご覧ください。

遅延読み込み画像は、ユーザーがページをスクロールすると読み込まれます。

このページでは、ブラウザで遅延読み込みを実装する方法について詳しく説明します。

ブラウザレベルの遅延読み込みを使用する理由

HTTP Archive によると、画像は、ほとんどのウェブサイトでリクエストが最も多いアセットタイプであり、通常は他のリソースよりも多くの帯域幅を消費します。90 パーセンタイルのサイトでは、パソコンとモバイルで 5 MB を超える画像が送信されています。

これまで、画面外の画像の読み込みを遅らせる方法は 2 つありました。

どちらの方法でも、デベロッパーは遅延読み込み動作を含めることができます。また、多くのデベロッパーは、より使いやすい抽象化を提供するサードパーティ ライブラリを構築しています。

ただし、遅延読み込みはブラウザが直接サポートしているため、外部ライブラリは必要ありません。また、ブラウザレベルの遅延読み込みにより、クライアントが JavaScript を無効にしていても、画像の読み込みが引き続き機能します。ただし、JavaScript が有効になっている場合にのみ、読み込みが延期されます。

loading 属性

Chrome では、画像がデバイスのビューポートに対して配置されている場所に応じて、異なる優先度で画像が読み込まれます。ビューポートより下にある画像は低い優先度で読み込まれますが、ページの読み込み時にも取得されます。

loading 属性を使用すると、画面外画像の読み込みを完全に延期できます。

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

loading 属性でサポートされている値は次のとおりです。

  • lazy: ビューポートから計算された距離に達するまで、リソースの読み込みを遅らせます。
  • eager: ブラウザのデフォルトの読み込み動作。この属性を含めない場合と同じで、ページ上の場所に関係なく画像が読み込まれます。これがデフォルトですが、明示的な値がないときにツールが loading="lazy" を自動的に追加する場合や、明示的に設定されていない場合はリンターからエラーが返される場合は、明示的に設定することをおすすめします。

loading 属性と取得優先度の関係

eager 値は、画像が画面外にある場合に読み込みをさらに遅らせることなく、通常どおりに画像を読み込む指示です。loading 属性がない別の画像よりも速く画像が読み込まれることはありません。

重要な画像(LCP イメージなど)の取得優先度を上げるには、取得の優先度fetchpriority="high" とともに使用します。

loading="lazy"fetchpriority="high" の画像は、画面外にある間も遅延が続き、ビューポートにほぼ近づいたときに優先度が高くなります。いずれにせよブラウザはその画像を優先度の高い状態で読み込む可能性があるため、この組み合わせは実際には必要ありません。

ビューポートからの距離のしきい値

スクロールせずにすぐに表示できる画像はすべて、通常どおり読み込まれます。デバイスのビューポートより下にある画像は、ユーザーがその近くでスクロールしたときにのみ取得されます。

Chromium の遅延読み込みの実装では、画面外画像がビューポートに表示される前に取得することで、ユーザーがスクロールするまでに読み込みが完了するように、画面外の画像が早期に読み込まれるようにします。

距離のしきい値は、次の要因によって変動します。

有効な接続タイプのさまざまなデフォルト値は、Chromium ソースで確認できます。DevTools でネットワークをスロットリングすると、これらのさまざまなしきい値を試すことができます。

データ節約とビューポートからの距離のしきい値の改善

2020 年 7 月、Chrome はデベロッパーの期待に応えるために、画像遅延読み込みのビューポートからの距離のしきい値を揃えるために大幅な改善を行いました。

高速接続(4G)では、Chrome のビューポートからの距離のしきい値を 3000px から 1250px に引き下げ、速度が遅い接続(3G 以下)ではしきい値を 4000px から 2500px に変更しました。この変更により、次の 2 つのことが実現されます。

  • <img loading=lazy> は、JavaScript の遅延読み込みライブラリにより提供されるエクスペリエンスに近い動作をします。
  • 新しいビューポートからの距離のしきい値は、ユーザーがスクロールするまでに画像が読み込まれている可能性が高いことを意味します。

高速接続(4G)でのデモの一つについて、新旧のビューポートからの距離のしきい値の比較を以下に示します。

以前のしきい値と新しいしきい値:

画像遅延読み込みの新しいしきい値が改善され、高速接続のビューポートからの距離のしきい値が 3,000 ピクセルから 1,250 ピクセルに引き下げられました。
ネイティブ遅延読み込みに使用される以前のしきい値と新しいしきい値の比較。

新しいしきい値と LazySizes(一般的な JavaScript 遅延読み込みライブラリ)の比較を以下に示します。

同じネットワーク条件で LazySizes が 70 KB を読み込むのに対し、Chrome では 90 KB の画像を読み込む新しいビューポートからの距離のしきい値。
Chrome と LazySizes で遅延読み込みに使用されるしきい値の比較。

画像にディメンション属性を指定する

ブラウザは画像を読み込みますが、明示的に指定しない限り、画像のサイズをすぐに把握することはできません。ブラウザがページ上に画像用の十分なスペースを予約し、混乱させるレイアウト シフトを避けるために、width 属性と height 属性をすべての <img> タグに追加することをおすすめします。

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

または、インライン スタイルで値を直接指定します。

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

ディメンションの設定に関するベスト プラクティスは、遅延読み込みを行うかどうかにかかわらず <img> タグに適用されますが、遅延読み込みを使用すると、重要性が増す可能性があります。

Chromium の遅延読み込みは、画像が表示されるとすぐに読み込まれる可能性が高くなるように実装されていますが、適切なタイミングで画像が読み込まれない可能性もあります。その場合、画像に widthheight を指定しないと、Cumulative Layout Shift への影響が大きくなります。画像のサイズを指定できない場合、遅延読み込みを行うと、レイアウト シフトが増加するリスクを冒してネットワーク リソースを節約できます。

ほとんどのシナリオでは、サイズを指定しなくても画像の読み込みが遅延しますが、注意すべきエッジケースがいくつかあります。widthheight が指定されていない場合、画像のサイズはデフォルトで 0x0 ピクセルになります。画像のギャラリーがある場合、各画像はスペースを占有せず、画像が画面外に押し出されないため、ブラウザは開始時にすべての画像がビューポート内に収まると判断する可能性があります。この場合、ブラウザはすべてを読み込むことを決定し、ページの読み込みが遅くなります。

多数の画像に対して loading がどのように動作するかの例については、こちらのデモをご覧ください。

<picture> 要素を使用して、定義した画像を遅延読み込みすることもできます。

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
  <img src="photo.jpg" loading="lazy">
</picture>

どの <source> 要素から読み込むかはブラウザが決定しますが、代替の <img> 要素に loading を追加するだけで済みます。

最初のビューポートで常に画像を積極的に読み込む

ユーザーが最初にページを読み込んだときに表示される画像の場合、特に LCP 画像の場合は、ブラウザのデフォルトの積極読み込みを使用して、すぐに利用できるようにします。詳細については、遅延読み込みが多すぎることによるパフォーマンスへの影響をご覧ください。

loading=lazy は、最初のビューポートの外側にある画像にのみ使用します。ブラウザは、ページ上の画像の位置がわかるまで画像を遅延読み込みできません。そのため、画像の読み込みが遅くなります。

<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">

<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">

グレースフル デグラデーション

loading 属性をサポートしていないブラウザはこの属性を無視します。遅延読み込みのメリットはありませんが、遅延読み込みを追加しても悪影響はありません。

よくある質問

Chrome で画像を自動的に遅延読み込みできますか?

これまで、ライトモードが Chrome for Android で有効になっていて、loading 属性が指定されていないか loading="auto" に設定されている場合、遅延に適したイメージは自動的に遅延読み込みされていました。ただし、ライトモードと loading="auto" は非推奨になりました。Chrome で画像を自動的に遅延読み込みする予定はありません。

画像を読み込む前にビューポートにどれだけ近づけておく必要があるかを変更できますか?

これらの値はハードコードされており、API では変更できません。ただし、今後、ブラウザでさまざまなしきい値の距離や変数がテストされるため、変更される可能性があります。

CSS の背景画像で loading 属性を使用できますか?

いいえ。<img> タグでのみ使用できます。

loading="lazy" を使用すると、表示されていない画像が計算された距離内にある場合に、画像が読み込まれないようにすることができます。これらの画像は、カルーセルの背後に表示される場合や、特定の画面サイズで CSS によって非表示になる場合があります。たとえば、Chrome、Safari、Firefox では、画像要素または親要素で display: none; スタイルを使用して画像が読み込まれることはありません。ただし、opacity:0 スタイル設定など、他の画像非表示手法では、ブラウザが画像を読み込みます。実装が常に入念にテストされ、意図したとおりに機能していることを確認してください。

Chrome 121 では、カルーセルなどの水平方向にスクロールする画像の動作が変更されました。これらは、垂直スクロールと同じしきい値を使用するようになりました。つまり、カルーセルのユースケースでは、画像はビューポートに表示される前に読み込まれます。つまり、ユーザーが画像の読み込みに気づく可能性は低くなりますが、その代わりにダウンロード数が増加します。水平遅延読み込みのデモを使用して、Chrome と Safari や Firefox での動作を比較します。

すでにサードパーティのライブラリやスクリプトを使用して画像の遅延読み込みを行っている場合はどうなりますか?

最新のブラウザに組み込まれている遅延読み込みは完全にサポートされているため、画像の遅延読み込みにサードパーティのライブラリやスクリプトは必要ありません。

loading="lazy" とともにサードパーティ ライブラリを引き続き使用する理由の 1 つは、属性をサポートしていないブラウザにポリフィルを提供する場合や、遅延読み込みがトリガーされるタイミングをより細かく制御するためです。

遅延読み込みに対応していないブラウザを扱うにはどうすればよいですか?{browsers-dont-support}

ポリフィルを作成するか、サードパーティ ライブラリを使用して、サイトで画像を遅延読み込みします。loading プロパティを使用して、ブラウザがこの機能をサポートしているかどうかを検出できます。

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

たとえば、lazysizes は一般的な JavaScript の遅延読み込みライブラリです。loading がサポートされていない場合にのみ、遅延サイズをフォールバック ライブラリとして読み込む loading 属性のサポートを検出できます。仕組みは次のとおりです。

  • <img src><img data-src> に置き換えて、サポートされていないブラウザでの積極的読み込みを回避します。loading 属性がサポートされている場合は、data-srcsrc に切り替えます。
  • loading がサポートされていない場合は、遅延サイズからフォールバックを読み込んで開始し、lazyload クラスを使用して遅延読み込みする画像を指定します。
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">

<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">

<script>
  if ('loading' in HTMLImageElement.prototype) {
    const images = document.querySelectorAll('img[loading="lazy"]');
    images.forEach(img => {
      img.src = img.dataset.src;
    });
  } else {
    // Dynamically import the LazySizes library
    const script = document.createElement('script');
    script.src =
      'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
    document.body.appendChild(script);
  }
</script>

このパターンのデモをご覧ください。古いブラウザで試して、代替の動作を確認してください。

iframe の遅延読み込みはブラウザでもサポートされていますか?

対応ブラウザ

  • 77
  • 79
  • 121
  • 16.4

<iframe loading=lazy> も標準化されました。これにより、loading 属性を使用して iframe を遅延読み込みできます。詳細については、オフスクリーン iframe を遅延読み込みする方法をご覧ください。

ブラウザレベルの遅延読み込みがウェブページ上の広告に与える影響

画像や iframe としてユーザーに表示されるすべての広告は、他の画像や iframe と同様に遅延読み込みを行います。

ウェブページが印刷されるとき、画像はどのように処理されますか?

すべての画像と iframe は、ページが印刷されるとすぐに読み込まれます。詳しくは、問題 #875403 をご覧ください。

Lighthouse では、ブラウザレベルの遅延読み込みは認識されますか?

Lighthouse 6.0 以降では、さまざまなしきい値を使用できる画面外画像の遅延読み込みのアプローチが考慮されており、画面外画像の遅延読み込みの監査に合格しています。

画像の遅延読み込みによるパフォーマンスの向上

ブラウザが画像の遅延読み込みをサポートしているため、ページのパフォーマンスを大幅に改善できます。

Chrome でこの機能を有効にすると、通常とは異なる動作がみられますか?バグを報告してください。