背景画像の遅延読み込み

Largest Contentful Paintを高速化するための背景画像の遅延読み込みとlazy load

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2024-11-27

背景画像を遅延させる。

背景画像はCore Web Vitalsにとって良い結果をもたらすことはほとんどありません。背景画像はレスポンシブではなく、ネイティブのloading属性にアクセスできず、背景画像の優先度をネイティブに制御することもできません。

背景画像はCore Web Vitalsに問題を引き起こすことがよくあります。重要でない背景画像を遅延させることで、多くの場合Core Web Vitalsが改善されます。

ウェブサイトに背景画像を使用するこのアンチパターンを非常によく見かけます。特にelementorのようなページビルダーを使用するWordPressサイトで顕著です。

  1. LCP画像(ヒーロー画像)を含むすべての画像がlazy loadされている
  2. 実際にはそれほど重要でない画像要素(スペーサー、検索ボックスの背景など)がスタイルシート内で背景画像としてリンクされている

lazy vs eager background images

この短い記事では、ページ上の他のより重要な画像を優先するために、これらの背景画像をlazy loadする方法をご紹介します。

注意事項!

まず注意事項から始めましょう!LCP要素が背景画像によって遅延している場合、それは設計上のミスであり、正しい方法で修正するべきです(LCP画像をpreloadする、LCP画像をlazy loadしない、背景画像の使用を完全に避ける)。しかし残念ながら、レガシーが多すぎて、サイトをできる限りパッチするしか短期的な代替手段がない場合もあります。そのような場合に、今回ご紹介する修正方法を適用できます!

方法1:すべてを遅延させる 

すべてを遅延させる方法は、やや力技的なアプローチです。しかし実装は簡単で、Core Web Vitalsの改善に効果的です!  この方法では、DOMContentLoadedイベントが発火するまですべての背景画像が遅延されます。これにより、ブラウザが最も重要なリソースを先にスケジュールするための余裕が生まれます。

手順は次のとおりです。まず、背景画像を持つすべての要素のbackground-imageスタイルプロパティをオーバーライドします。DOMコンテンツが読み込まれたら、このオーバーライドを削除します。その時点で、背景画像以外の画像はダウンロードキューに入っているでしょう。このタイミングで、重要度の低い背景画像をダウンロードキューに追加するのが最適です。

コード

まず、スタイルを作成してページのHEADに配置します。このスタイルにはidを付けることが重要です。後でこのidを使ってこのスタイルタグを削除するためです。もちろん、ワイルドカード(*)の代わりに、実際に背景画像を持つCSSクラス名のみを指定することもできます。

<style id="no-bg-img">
    *{background-image:none!important}
</style>

次に、DOMコンテンツが読み込まれると、LCP画像はおそらくすでにダウンロードキューに入っているでしょう。この時点で背景画像をキューに追加しても安全です。 

<script>
    window.addEventListener('DOMContentLoaded',function(){
        document.getElementById('no-bg-img').remove();
    })
</script>

LCPが早期ダウンロードをトリガーしない場合、おそらくJavaScriptが原因です。その場合は、「DOMContentLoaded」を「load」イベントに切り替えてみてください。

適用前

late lcp caused by background image

適用後

early lcb after lazy background images

方法2:背景画像をLazy Loadする

背景画像のlazy load方法は、やや上品で高度なアプローチであり、個別の対応が必要です。 

仕組みは次のとおりです。まず、背景画像を持つすべての要素を手動で特定します。それらの要素にクラス名(.lazybg)を追加する必要があります。次に、intersection observerでこれらの要素を監視し、表示領域に近づいたら背景画像をlazy loadします。

コード

まず、スタイルを作成してページのHEADに配置します。このスタイルは前のスタイルに似ていますが、ページ上のすべての要素の背景画像プロパティを削除する代わりに、特定のクラス名を持つ要素のみを対象とします。

<style>
    .lazybg {background-image: none !important}
</style>

次に、DOMコンテンツが読み込まれたら、背景画像を持つ要素の監視を開始します。その要素がビューポートにスクロールされると、.lazybgクラスを削除して背景画像のダウンロードをトリガーします。 

<script>
window.addEventListener('DOMContentLoaded', (event) => {

  // all elements wioth background images that should be lazy loaded 
  const lazyImages = document.querySelectorAll('.lazybg');
 
  // options for the observer
  const backgroundOptions = {
     threshold: 0,
     rootMargin: "0px 0px 50px 0px"
  };

  // the observer
  const imageObserver = new IntersectionObserver((entries, imageObserver) => {
     entries.forEach(entry => {
         if (entry.isIntersecting) {
             showImageBackground(entry.target);
             imageObserver.unobserve(entry.target);
         }
     });
  }, backgroundOptions);

    
  // observe each image
  lazyImages.forEach(image => {
     imageObserver.observe(image);
  });

  // show background image
  function showImageBackground(node) {
     node.classList.remove('lazybg');
  }
});
</script>

この方法の利点は、表示領域外の背景画像がダウンロードキューに入らないことです。これにより、読み込み段階でブラウザのリソースが解放されます。

適用前

late lcp caused by background image

適用後

background images delayed with the intersection observer

まとめ

どちらの方法も、Largest Contentful Paint画像のようなより重要な画像を優先するために背景画像を遅延させる効果があります。最初の方法は実装が非常に簡単で、すぐに結果が得られます。2番目の方法は背景画像に本格的なlazy load動作を追加し、より大きなページスピードの向上をもたらします。 

これらの方法を適用する際は注意してください。背景画像を遅延させる必要がある場合、そのページは私が「設計上低速」と呼ぶ状態です。これを修正する望ましい方法は、ページを書き直して背景画像の使用を避けることです。

Stop debating in Jira.

Get a definitive answer on your performance issues. I deliver a granular breakdown of your critical rendering path.

Book a Deep Dive >>

  • Definitive Answers
  • Granular Breakdown
  • Critical Path Analysis
背景画像の遅延読み込みCore Web Vitals 背景画像の遅延読み込み