JavaScript > Performance Optimization > Optimizing Code > Lazy loading

Lazy Loading Images with Intersection Observer

Improve website performance by lazy loading images. This snippet uses the Intersection Observer API to load images only when they are about to enter the viewport, reducing initial load time and bandwidth consumption.

Concepts Behind Lazy Loading

Lazy loading is a technique that defers the loading of non-critical resources at page load time. Instead, these non-critical resources are loaded at the moment of need. For images, this means loading them when the user scrolls down the page and the images become visible. This reduces the initial page load time and conserves bandwidth, resulting in a faster and more responsive user experience.

The Intersection Observer API

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport. It's a highly performant way to determine when an element is visible without relying on scroll events that can degrade performance.

Code Implementation

This code snippet first defines the HTML markup with 'img' tags that have a class of 'lazy' and the actual image source stored in the 'data-src' attribute. The JavaScript code then selects all elements with the class 'lazy'. It checks if the Intersection Observer API is supported. If it is, a new Intersection Observer is created, which observes each lazy image. When an image intersects with the viewport, its 'src' attribute is updated with the value from 'data-src', effectively loading the image, and the observer stops watching that image. A fallback is provided for older browsers that don't support the API, which simply loads all images on page load.

<!-- HTML Markup -->
<img class="lazy" data-src="image1.jpg" alt="Image 1">
<img class="lazy" data-src="image2.jpg" alt="Image 2">
<img class="lazy" data-src="image3.jpg" alt="Image 3">


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

 if ('IntersectionObserver' in window) {
 const lazyImageObserver = new IntersectionObserver(function(entries, observer) {
 entries.forEach(function(entry) {
 if (entry.isIntersecting) {
 const lazyImage = entry.target;
 lazyImage.src = lazyImage.dataset.src;
 lazyImage.classList.remove('lazy');
 lazyImageObserver.unobserve(lazyImage);
 }
 });
 });

 lazyImages.forEach(function(lazyImage) {
 lazyImageObserver.observe(lazyImage);
 });
 } else {
 // Fallback for browsers that don't support Intersection Observer
 lazyImages.forEach(function(lazyImage) {
 lazyImage.src = lazyImage.dataset.src;
 });
 }
});
</script>

Real-Life Use Case

Imagine an e-commerce website with many product images. Lazy loading ensures that only the images currently visible to the user are loaded, significantly improving the initial page load time. This leads to a better user experience, especially on mobile devices with limited bandwidth or slower internet connections. It can also drastically reduce server costs as fewer images are loaded unnecessarily.

Best Practices

Always provide a placeholder for lazy-loaded images to prevent layout shifts as the images load. Set explicit width and height attributes on the 'img' tags to reserve space. Consider using a low-quality placeholder image (LQIP) or a blurred version of the actual image for a better user experience while the full image is loading. Use a polyfill for Intersection Observer to support older browsers if necessary.

Interview Tip

When discussing lazy loading in an interview, emphasize the benefits of improved page load time, reduced bandwidth consumption, and enhanced user experience. Be prepared to explain the Intersection Observer API and its advantages over traditional scroll event-based lazy loading implementations. Mention fallback strategies for older browsers.

When to Use Lazy Loading

Use lazy loading when you have a large number of images on a page, especially if most of them are initially below the fold (not visible without scrolling). Lazy loading is also beneficial for websites with a lot of video content or other heavy resources that are not immediately needed. Avoid using lazy loading for critical above-the-fold content, as this can delay the initial rendering of the page.

Memory Footprint

Lazy loading reduces the memory footprint of a web page by loading resources only when needed. This is especially important for mobile devices with limited memory. By avoiding loading unnecessary images and other assets, lazy loading helps to prevent out-of-memory errors and improves overall performance.

Alternatives

While Intersection Observer is the preferred method, other approaches exist, such as using scroll events to detect when an image is near the viewport. However, scroll event-based solutions are generally less performant and can lead to janky scrolling. Another alternative is using a JavaScript library that provides lazy loading functionality. However, using a library adds to the overall size of your application.

Pros

  • Improved initial page load time.
  • Reduced bandwidth consumption.
  • Enhanced user experience, especially on mobile devices.
  • Reduced server load.

Cons

  • Requires JavaScript.
  • Potential for layout shifts if placeholders are not used correctly.
  • Requires careful planning to avoid delaying the loading of critical content.

FAQ

  • What happens if the user has JavaScript disabled?

    If JavaScript is disabled, the lazy loading functionality will not work. It's best to have a <noscript> fallback to load all images in this case or a server-side rendered solution.
  • How can I improve the loading experience while the image is being fetched?

    You can use a placeholder image, a low-quality image placeholder (LQIP), or a blurred image as a background until the actual image loads. You can also use CSS to display a loading spinner or progress bar.
  • Does lazy loading affect SEO?

    If implemented correctly, lazy loading should not negatively affect SEO. Search engine crawlers can execute JavaScript and render the page, so they should be able to see the lazy-loaded images. Ensure that the images have proper 'alt' attributes and are accessible to crawlers. Server-side rendering is always a great option for SEO friendly pages.