Webページの表示を高速化するために、ページロード初期時には画像は読み込まず、表示できるデータが存在するようになってから表示することをLazyLoad(遅延読み込み)と言います。今回は、Intersection Observerを使って、LazyLoadを作る方法について紹介したいと思います。
Intersection Observerとは
このIntersection Observerは、比較的新しいAPIで、「Intersection(要素間交差)」を「Observe(監視)」するためのAPIです。 任意の要素(DOM)同士の交差を監視することが出来ます。デフォルトでviewport(見えている範囲)とある要素が交差=ある要素が見えたら何かする、というものです。詳しくは、こちらを参照して下さい。
サンプルコード
image_containerというidが割り振られたdiv要素の中に複数の画像要素があるケースでは、下記のような形で利用します。
const load = () => { const loadImage = (target) => { target.addEventListener("load", () => { setTimeout(() => el.classList.add("loaded"), 500); }) target.addEventListener("error", () => { console.log("error") }) target.src = target.dataset.url } const el = document.getElementById("image_container") const observer = new IntersectionObserver((entries, observer) => { entries.forEach(function(entry) { if (entry.isIntersecting) { const images = el.querySelectorAll('img') console.log(images) images.forEach((imgEl) => { loadImage(imgEl) }) observer.unobserve(el) } }) }) observer.observe(el) } window.addEventListener('load', load)
JSの処理についてざっくり話すと、遅延読み込みしたい要素をIntersection Observerで監視するよう設定しています。この要素の子要素には、複数のimgタグがある想定です。
ビューポートに少しでも要素が交差したら、data-url属性に指定している画像をロードするという処理になっています。
Vue/Nuxtでこれを実装する場合は、ディレクティブのinsertedと組み合わせて、上記処理を行うようにするとLazyLoadするimgコンポーネントが実装できます。
昔は、scrollイベントとなどと組み合わせてlazyload機能を実装するなどして、あまり独自に実装するということがなかったかもしれませんが、Intersection Observerを利用することでシンプルに実装ができます。お疲れさまでした。