Skip to main content
Andrea Verlicchi

Making the web faster and more user-friendly

Do we still need lazy loading libraries and `data-src`?

Back in the day, when browser support for native lazy loading wasn’t widespread, the best practice was to use data-src attributes and a JavaScript library like my vanilla-lazyload to load images as they entered the viewport. Is this still best practice today?

What is lazy loading? #

Lazy loading images is a technique to defer the loading of below-the-fold images until they are about to enter the viewport (the visible portion of the page). This technique saves bandwidth, reduces CDN costs, lowers the website's carbon footprint, and improves page rendering time, particularly the Largest Contentful Paint.

JavaScript-driven image lazy loading #

Traditionally, lazy loading images involved replacing the src attribute with a data-src attribute and using JavaScript to detect when the images are nearing the viewport, then copy the data attributes into the proper ones, triggering their deferred loading.

<img
  data-src="turtle.jpg"
  alt="Lazy turtle"
  class="lazy"
/>

Native lazy loading #

With native lazy loading, AKA browser-level lazy loading, simply add the loading="lazy" attribute to the <img> tag.

<img
  src="turtle.jpg"
  alt="Lazy turtle"
  loading="lazy"
/>

This works on all modern browsers.

Do we still need JavaScript-driven lazy loading? #

No, unless you want greater control over the lazy loading process.

Let's see what are the cases for using JavaScript-driven lazy loading, instead of just using loading="lazy".

1. Supporting users on slow or faulty connections #

JavaScript libraries like vanilla-lazyload can cancel the download of images that leave the viewport and retry downloads if interrupted, enhancing the user experience on slow connections.

A use case for that is:

Native lazy loading makes browsers download lazy images from top to bottom, resulting in a delay to show the bottom images.

Javascript libraries like vanilla-lazyload will cancel the download of images that exit the viewport, keeping users' bandwidth focused on the images currently in the viewport.

Another use case is:

vanilla-lazyload will retry downloading those images when the network connection is restored.

You can try these features on any of the vanilla-lazyload demos, like the basic case demo, and throttling or disabling your connection speed in the developer tools of your browser.

2. Advanced callbacks or CSS classes #

JavaScript-driven lazy loading provides callbacks and CSS classes for various events (start loading, finish loading, error, enter viewport, exit viewport, etc.), allowing for enhanced visual effects and monitoring.

Those callbacks and CSS classes can be very helpful to create visual effects on your page.

Find more about callbacks and classes in vanilla-lazyload API / options.

3. Optimizing web performance, specifically Largest Contentful Paint #

JavaScript-driven lazy loading offers more control over which images are downloaded, helping to optimize the Largest Contentful Paint (LCP).

With native lazy loading, you don't have control over what images get downloaded from the browser.

The use case:

Native lazy loading would start downloading those images, which will share the bandwidth with the download of your LCP image, while you want to download the latter with the highest priority.

JavaScript-driven lazy load like vanilla-lazyload provide APIs and options to fine-grain control how far off-the-viewport images should be to start downloading.

4. Lazy loading other assets #

For lazy loading background images, videos, animated SVGs, and more, a JavaScript library like vanilla-lazyload is still required.

Find out more #

Check the vanilla-lazyload documentation or my blog post lazy load responsive images in 2020.