DEV Community

Cover image for How to Implement Lazy Loading for Images with JavaScript
Rowsan Ali
Rowsan Ali

Posted on

How to Implement Lazy Loading for Images with JavaScript

In modern web development, optimizing performance is crucial for delivering a smooth user experience. One common technique to improve page load times is lazy loading. Lazy loading delays the loading of non-critical resources, such as images, until they are needed. This means that images are only loaded when they come into the user's viewport, reducing the initial page load time and saving bandwidth.

In this blog post, we’ll explore how to implement lazy loading for images using JavaScript. We’ll cover the following topics:

  1. What is Lazy Loading?
  2. Why Use Lazy Loading?
  3. Implementing Lazy Loading with JavaScript
  4. Using the Intersection Observer API
  5. Fallback for Older Browsers
  6. Lazy Loading with Native HTML Attributes

Let’s dive in!


1. What is Lazy Loading?

Lazy loading is a design pattern that defers the loading of resources until they are actually needed. For images, this means that instead of loading all images when the page loads, images are only loaded when they are about to enter the viewport (the visible area of the webpage).

This technique is particularly useful for pages with a large number of images or long-scrolling pages, where not all images are visible to the user immediately.


2. Why Use Lazy Loading?

  • Improved Page Load Time: By loading only the images that are visible, the initial page load time is significantly reduced.
  • Bandwidth Savings: Users on slow connections or limited data plans benefit from reduced data usage.
  • Better User Experience: Faster load times lead to a smoother and more responsive experience.
  • SEO Benefits: Search engines favor faster-loading websites, which can improve your search rankings.

3. Implementing Lazy Loading with JavaScript

To implement lazy loading, we’ll use JavaScript to detect when an image enters the viewport and then load it dynamically. Here’s a step-by-step guide:

Step 1: Modify the HTML

First, we need to modify the HTML to prevent images from loading immediately. Instead of using the src attribute, we’ll use a data-src attribute to store the image URL.

<img class="lazy" data-src="path/to/image.jpg" alt="Description of image">
Enter fullscreen mode Exit fullscreen mode

Step 2: Write the JavaScript

Next, we’ll write JavaScript to load the images when they enter the viewport.

document.addEventListener("DOMContentLoaded", function() {
  const lazyImages = document.querySelectorAll("img.lazy");

  const lazyLoad = (image) => {
    image.src = image.dataset.src;
    image.classList.remove("lazy");
  };

  const lazyImageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        lazyLoad(entry.target);
        observer.unobserve(entry.target);
      }
    });
  });

  lazyImages.forEach((image) => {
    lazyImageObserver.observe(image);
  });
});
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • DOMContentLoaded Event: The script runs after the DOM is fully loaded.
  • querySelectorAll: Selects all images with the lazy class.
  • IntersectionObserver: Observes when images enter the viewport.
  • lazyLoad Function: Sets the src attribute to the value of data-src and removes the lazy class.

4. Using the Intersection Observer API

The IntersectionObserver API is a modern and efficient way to detect when an element enters the viewport. It’s widely supported in modern browsers and provides better performance compared to older methods like scroll event listeners.

Key Features of IntersectionObserver:

  • Efficient: The browser optimizes the observation process, reducing performance overhead.
  • Asynchronous: Works in the background without blocking the main thread.
  • Customizable: You can configure the root margin and threshold for intersection detection.

5. Fallback for Older Browsers

For older browsers that do not support the IntersectionObserver API, we can provide a fallback using scroll event listeners.

if (!("IntersectionObserver" in window)) {
  const lazyImages = document.querySelectorAll("img.lazy");

  const lazyLoad = () => {
    lazyImages.forEach((image) => {
      if (image.getBoundingClientRect().top <= window.innerHeight && image.getBoundingClientRect().bottom >= 0 && getComputedStyle(image).display !== "none") {
        image.src = image.dataset.src;
        image.classList.remove("lazy");
      }
    });
  };

  document.addEventListener("scroll", lazyLoad);
  window.addEventListener("resize", lazyLoad);
  window.addEventListener("orientationchange", lazyLoad);
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • getBoundingClientRect: Checks if the image is within the viewport.
  • Scroll Event Listener: Listens for scroll events to trigger lazy loading.

6. Lazy Loading with Native HTML Attributes

Modern browsers also support native lazy loading for images using the loading attribute. This is the simplest way to implement lazy loading without JavaScript.

<img src="path/to/image.jpg" loading="lazy" alt="Description of image">
Enter fullscreen mode Exit fullscreen mode

Browser Support:

  • Chrome: Supported
  • Firefox: Supported
  • Edge: Supported
  • Safari: Supported (from version 15.4)

When to Use Native Lazy Loading:

  • If you only need basic lazy loading and don’t require advanced customization.
  • For simpler projects where browser support is not a concern.

Conclusion

Lazy loading is a powerful technique to optimize web performance, especially for image-heavy websites. By implementing lazy loading with JavaScript, you can significantly improve page load times and enhance the user experience.

In this post, we covered:

  • The basics of lazy loading.
  • How to implement it using JavaScript and the IntersectionObserver API.
  • A fallback for older browsers.
  • Native lazy loading with the loading attribute.

By combining these techniques, you can ensure that your website performs well across all devices and browsers. Happy coding!

I made a free project tracker in Notion. It has a dashboard. Check it out if you're interested.

Feel free to experiment with the code examples provided and adapt them to your specific use case.

Top comments (1)

Collapse
 
kelvincode1234 profile image
Precious Kelvin Nwaogu

Thanks for sharing this topic! I've only implemented lazy loading using CSS so far, but this JavaScript approach is definitely on my list to try out soon.