JavaScript

Intersection Observer APIで遅延読み込みを最適化する方法

Webページの表示速度は、ユーザー体験(UX)やSEOに大きく影響します。特に、画像やコンテンツの遅延読み込み(Lazy Loading)は、不要なリソースのロードを抑えることで、パフォーマンスを向上させる有効な手法です。

本記事では、Intersection Observer APIを活用した遅延読み込みの基本から応用テクニックまでを詳しく解説します。従来の手法との違いや具体的なコード例、パフォーマンス最適化のポイントについても紹介しますので、ぜひ最後までご覧ください。

1. 遅延読み込みとIntersection Observer API

遅延読み込みの重要性

Webページの読み込み速度は、直帰率やコンバージョン率に直結します。以下のデータからも、ページの表示が遅いとユーザーの離脱率が上昇することが分かります。

ページ表示時間 直帰率上昇率
1秒 → 3秒 約32%上昇
1秒 → 5秒 約90%上昇
1秒 → 10秒 約123%上昇

出典:Google「The need for mobile speed」(2017)

遅延読み込みを適切に実装すれば、不要なリソースの読み込みを防ぎ、ページ表示を高速化できます。

従来の遅延読み込み手法の課題

過去には、scrollイベントを使った方法が主流でしたが、以下のような課題がありました。

  • パフォーマンスが低い(スクロールのたびに計算が発生)
  • 正確性が低い(要素が画面に表示されたかどうかを厳密に判定しにくい)
  • コードが煩雑(複雑なロジックが必要)

これらの課題を解決するのが、Intersection Observer API です。

Intersection Observer APIとは

Intersection Observer API は、要素がビューポート(画面領域)に入ったかどうかを監視するAPI です。これにより、効率的な遅延読み込みが可能になります。

主な特徴

スクロールイベントを使わずに要素の可視状態を監視
最適化された非同期処理でパフォーマンス向上
簡潔なコードで実装可能
複数の要素を同時に監視できる

対応ブラウザは以下の通りです。

ブラウザ 対応バージョン
Chrome 51以上
Firefox 55以上
Edge 16以上
Safari 12.1以上

(※Internet Explorerは非対応ですが、Polyfillを使えば利用可能)

 

2. 基本的な実装方法

まずは、Intersection Observer APIを使った基本的な画像の遅延読み込みを実装してみましょう。

コード例(シンプルな遅延読み込み)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>遅延読み込みデモ</title>
    <style>
        .image-container {
            min-height: 300px;
            text-align: center;
            margin-bottom: 20px;
        }
        .lazy {
            opacity: 0;
            transition: opacity 0.5s;
        }
        .lazy.loaded {
            opacity: 1;
        }
    </style>
</head>
<body>

    <div class="image-container">
        <img data-src="example.jpg" class="lazy" width="400" height="300" alt="サンプル画像">
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            let lazyImages = document.querySelectorAll(".lazy");

            let observer = new IntersectionObserver(function (entries, observer) {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        let img = entry.target;
                        img.src = img.getAttribute("data-src");
                        img.classList.add("loaded");
                        observer.unobserve(img);
                    }
                });
            });

            lazyImages.forEach(img => observer.observe(img));
        });
    </script>

</body>
</html>

 

コードのポイント

  • IntersectionObserver を使って、画像が画面に入ったタイミングでsrc属性を設定
  • observer.unobserve(img); で監視を解除し、不要な処理を減らす

 

3. 応用テクニック

複数要素を効率的に監視する

複数の画像や動画を一括で監視することも可能です。

let observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            let element = entry.target;
            element.src = element.getAttribute("data-src");
            element.classList.add("loaded");
            observer.unobserve(element);
        }
    });
}, { threshold: 0.5 });  // 50%見えたら読み込む

 

threshold: 0.5 を設定すると、要素が50%以上表示されたときに読み込むようになります。

 

4. 無限スクロールの実装

SNSやブログ記事一覧などで使われる無限スクロールの実装も、Intersection Observer APIで簡単にできます。

無限スクロールのコード例

let observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            loadMoreContent(); // 次のコンテンツをロード
        }
    });
});

observer.observe(document.querySelector("#loadTrigger"));

 

  • 画面下部の要素が表示されたら、新しいコンテンツをロード
  • #loadTrigger は仮の要素で、実際にはフッターの手前に設置すると効果的

 

5. まとめ

  • Intersection Observer APIを使うと、シンプルなコードで高パフォーマンスな遅延読み込みが可能
  • スクロールイベントよりも軽量で、パフォーマンスに優れる
  • 画像だけでなく、動画や無限スクロールにも応用可能
ABOUT ME
りん
このブログでは、Web開発やプログラミングに関する情報を中心に、私が日々感じたことや学んだことをシェアしています。技術と生活の両方を楽しめるブログを目指して、日常で触れた出来事や本、ゲームの話題も取り入れています。気軽に覗いて、少しでも役立つ情報や楽しいひとときを見つけてもらえたら嬉しいです。