Lazy loading images

 Images can be displayed on web pages by inlining them as <img> elements in HTML, or as CSS background images. In this article, you'll learn how to lazy load both types of images.

Embedded image

The most common lazy-loaded images are those used in <img> elements. For inline images, we have three lazy-loading options that can be combined for optimal cross-browser compatibility:

  • Use browser-level lazy loading
  • Using Intersection Observer

Use browser-level lazy loading
Both Chrome and Firefox support lazy loading via the loading attribute. This attribute can be added to the <img> element, or to the <iframe> element. The lazy value tells the browser to load images immediately if they are in the viewport, and fetch additional images as the user scrolls near them.

Note that <iframe loading="lazy"> is not yet a standard specification. Although implemented in Chromium, it is not yet standardized and may change in the future. We recommend not lazy loading iframes using the loading attribute until it is included in the spec.

For details on browser support, see the loading field of the MDN browser compatibility table. If the browser does not support lazy loading, this attribute will be ignored and the image will load immediately as usual.

For most sites, adding this attribute to inline images can improve performance and prevent users from loading images they may never see. If your site has a lot of images and you want to ensure that users of browsers that don't support lazy loading benefit, you'll need to combine this with one of the methods explained below.

To learn more, check out Browser-Level Lazy Loading for the Web.

Using Intersection Observer
To populate the lazy loading of the <img> elements, we use JavaScript to check if they are in the viewport. If in the viewport, their src (and sometimes srcset ) attributes are populated with URLs pointing to the desired image content.

If you've written lazy loading code before, you've probably done it by using event handlers like scroll or resize. While this approach works best across major browsers, modern browsers offer a more performant and efficient way to do the work of checking element visibility through the Intersection Observer API.

Compared to code that relies on various event handlers, Intersection Observer is easier to use and read, because you only need to register an observer to observe the element, without writing tedious element visibility detection code. All that remains is to decide what to do when the element becomes visible. Let's assume this basic markup pattern for lazy loaded <img> elements

 <img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" 
alt="I'm an image!">
You should focus on three related parts of this markup:
  • class attribute, which is the attribute you will select elements with in JavaScript.
  • src attribute, which references a placeholder image that will appear when the page first loads.
  • The data-src and data-srcset attributes, which are placeholder attributes containing URLs for images that will be loaded once the element appears in the viewport.

Now let's see how to lazy load images with this markup pattern using Intersection Observer in JavaScript:
document.addEventListener("DOMContentLoaded", function() {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

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

lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Possibly fall back to event handlers here
}
});

In the document's DOMContentLoaded event, this script queries the DOM for all lazy <img> elements. If Intersection Observer is available, creates a new observer that runs a callback when an img.lazy element enters the viewport.

Intersection Observer works in all modern browsers. So using it as a polyfill for loading="lazy" will ensure lazy loading is available to most visitors.

Images in CSS

While the <img> tag is the most common way to use images on web pages, images can also be invoked through the CSS background-image property (and others). Browser-level lazy loading doesn't work with CSS background images, so if you have background images that you want to lazy load, you need to consider other options.

Unlike the <img> element, which loads regardless of visibility, image loading behavior in CSS requires more speculation. When building the document and CSS object model and rendering the tree, the browser checks how the document's CSS is applied before requesting an external resource. If the browser determines that a CSS rule involving an external resource does not apply to the currently constructed document, the browser will not request that resource.

You can use this speculative behavior to delay image loading in CSS by using JavaScript to determine when an element appears in the viewport, and then applying a class to that element that calls a background-image. This downloads images on demand, rather than on initial load. For example, let's take an element with a large hero background image:
 <div class="lazy-background">
<h1>Here's a hero heading to get your attention!</h1>
<p>Here's hero copy to convince you to buy a thing!</p>
<a href="/buy-a-thing">Buy a thing!</a>
</div>

The div.lazy-background element usually contains a hero background image called by some CSS. However, in this lazy loading example, you can isolate the background-image property of the div.lazy-background element by adding the visible class to the element in the viewport

 .lazy-background {
background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
background-image: url("hero.jpg"); /* The final image */
}
From here, use JavaScript to check if the element is in the viewport (use Intersection Observer!), then add the visible class to the div.lazy-background element when the element is in viewport, at which point the image will load:
document.addEventListener("DOMContentLoaded", function() {
var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

if ("IntersectionObserver" in window) {
let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
lazyBackgroundObserver.unobserve(entry.target);
}
});
});

lazyBackgrounds.forEach(function(lazyBackground) {
lazyBackgroundObserver.observe(lazyBackground);
});
}
});
Lazy loading libraries

The following libraries can be used to lazy load images.

  • lazysizes is a full-featured lazy loading library that can lazy load images and iframes. It uses a pattern very similar to the code samples in this article, in that it automatically binds to the lazyload class on <img> elements and requires you to specify the image's URL in the data-src and/or data-srcset attributes, and will Its contents are swapped to the src and/or srcset attributes respectively. It uses Intersection Observer (which can be polyfilled) and can be extended with a number of plugins to do things like lazy load videos. Learn more about using lazysizes.
  • vanilla-lazyload is a lightweight option for lazy loading images, background images, videos, iframes and scripts. It utilizes Intersection Observer, supports responsive images, and enables browser-level lazy loading.
  • lozad.js is another lightweight option that only uses Intersection Observer. So it performs well, but needs to be polyfilled before it will work on older browsers.
  • If you need to use a React-specific lazy-loading library, consider react-lazyload. While it doesn't use Intersection Observer, it does provide a familiar approach to lazy loading images for those who are used to developing applications with React

Popular posts from this blog

大学资料分享——广工计院各个科目实验报告、课设及期末复习资料!!

Win10 远程计算机或设备将不接受连接

JAVA Traffic Signal Light Course Design (Source Code + Report + Video Demonstration)

Implementation of Ajax Interceptor