Recipe 6.1

Lazy Loading an Image

The demo area is scrollable. There is an image that is initially hidden. If you start to scroll down, the image won’t load until it becomes visible in the viewport.

It doesn’t wait for the image to be fully within the viewport. As soon as it becomes partially visible, the image loads.

Demo

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit nunc vitae luctus varius. Quisque nisl purus, accumsan et hendrerit et, ornare sed lectus. Sed risus lacus, consequat ac molestie nec, molestie ac dui. Donec iaculis laoreet leo id molestie. Fusce eu quam ut nisl interdum mollis. Phasellus mollis magna at commodo aliquam. Aenean convallis nibh est, a eleifend sapien eleifend ut. Curabitur tincidunt nisi et tincidunt vehicula. Praesent gravida malesuada odio, vitae condimentum leo rutrum vitae. Praesent euismod sem sed efficitur laoreet. Morbi id nisl enim. Vivamus euismod consectetur eleifend. Aenean congue tellus leo, varius hendrerit justo aliquam a. Donec eu condimentum lorem, ut condimentum magna. Donec aliquam volutpat iaculis.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit nunc vitae luctus varius. Quisque nisl purus, accumsan et hendrerit et, ornare sed lectus. Sed risus lacus, consequat ac molestie nec, molestie ac dui. Donec iaculis laoreet leo id molestie. Fusce eu quam ut nisl interdum mollis. Phasellus mollis magna at commodo aliquam. Aenean convallis nibh est, a eleifend sapien eleifend ut. Curabitur tincidunt nisi et tincidunt vehicula. Praesent gravida malesuada odio, vitae condimentum leo rutrum vitae. Praesent euismod sem sed efficitur laoreet. Morbi id nisl enim. Vivamus euismod consectetur eleifend. Aenean congue tellus leo, varius hendrerit justo aliquam a. Donec eu condimentum lorem, ut condimentum magna. Donec aliquam volutpat iaculis.

Code

JavaScript
/**
 * Observes an image element for lazy loading.
 * 
 * @param img a reference to the image DOM node
 * @param url the URL of the image to load
 */
function lazyLoad(img, url) {
  const observer = new IntersectionObserver(entries => {
    // Since there's only one image being observed, there is only one entry.
    // If you are observing multiple images, they may start intersecting at the same time,
    // in which case the entries array would have more than one entry.
    if (entries[0].isIntersecting) {
      console.log('Loading image');
      img.src = url;
      observer.disconnect();
    }
  });

  observer.observe(img);
}

lazyLoad(document.querySelector('#lazy-image'), 'https://placekitten.com/300/300');
HTML
<div style="max-height: 20em; overflow: auto;">
  <h2>Lorem Ipsum</h2>
  <p class="fs-5">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit nunc vitae luctus varius. Quisque nisl
    purus, accumsan et hendrerit et, ornare sed lectus. Sed risus lacus, consequat ac molestie nec, molestie ac dui.
    Donec
    iaculis laoreet leo id molestie. Fusce eu quam ut nisl interdum mollis. Phasellus mollis magna at commodo aliquam.
    Aenean convallis nibh est, a eleifend sapien eleifend ut. Curabitur tincidunt nisi et tincidunt vehicula. Praesent
    gravida malesuada odio, vitae condimentum leo rutrum vitae. Praesent euismod sem sed efficitur laoreet. Morbi id
    nisl
    enim. Vivamus euismod consectetur eleifend. Aenean congue tellus leo, varius hendrerit justo aliquam a. Donec eu
    condimentum lorem, ut condimentum magna. Donec aliquam volutpat iaculis.
  </p>

  <p class="fs-5">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas blandit nunc vitae luctus varius. Quisque nisl
    purus, accumsan et hendrerit et, ornare sed lectus. Sed risus lacus, consequat ac molestie nec, molestie ac dui.
    Donec
    iaculis laoreet leo id molestie. Fusce eu quam ut nisl interdum mollis. Phasellus mollis magna at commodo aliquam.
    Aenean convallis nibh est, a eleifend sapien eleifend ut. Curabitur tincidunt nisi et tincidunt vehicula. Praesent
    gravida malesuada odio, vitae condimentum leo rutrum vitae. Praesent euismod sem sed efficitur laoreet. Morbi id
    nisl
    enim. Vivamus euismod consectetur eleifend. Aenean congue tellus leo, varius hendrerit justo aliquam a. Donec eu
    condimentum lorem, ut condimentum magna. Donec aliquam volutpat iaculis.
  </p>

  <img id="lazy-image">
</div>
Web API Cookbook
Joe Attardi