Native lazy-loading of images with zero Javascript

pfacklam

Paul Facklam

Posted on February 8, 2021

Native lazy-loading of images with zero Javascript

About lazy-loading and why you should use it

The worldwide web has evolved over the past decades and today's websites consist not only of text and color, but also of countless media content. First and foremost images.



<img src="/path/to/your/image.jpg" alt="Awesome image" />


Enter fullscreen mode Exit fullscreen mode

But what does this have to do with lazy-loading?

Lazy-loading is a technique that defers loading of non-critical resources at page load time. Instead, these non-critical resources are loaded at the moment of need. Where images are concerned, "non-critical" is often synonymous with "off-screen".
-- from web.dev/lazy-loading written by Jeremy Wagner and Rachel Andrew

This means by using lazy-loading we achieve the following benefits over the classic embedding in HTML:

  • Performance Gains - With lazy-loading we can improve loading speed by reducing the number of images that need to be loaded initially.
  • Cost reduction - A lazy loaded image may never need to load because the user never reaches the image's position on the page.

Ok, sounds good. How can we make that happen? What do we need for this? Let's get started!

The old (Javascript) approach

There are a lot of snippets and scripts like vanilla-lazyload out there that enable lazy-loading via javascript. In almost all cases a data attribute is used to prevent upfront image loading.


 html
<img data-src="/path/to/your/image.jpg" alt="Awesome image" />


Enter fullscreen mode Exit fullscreen mode

But how is the image loaded at all? To achieve this, one of the following two techniques is usually used.

Event listeners

This technique uses event listeners on the scroll, resize and orientationChange events in the browser. If one of the mentioned events is fired and assuming the image enters the viewport the data-src attribute is replaced with the src attribute to trigger the loading call. See it in action:

Intersection Observer API

Unlike the first method, the image is observed (asynchronously) by using the IntersectionObserver API. The image is then loaded by changing the data-src to src attribute as soon as it enters the viewport.

But what if I told you that you don't need Javascript at all? 😲 Yes, you heard right! Zero Javascript.

The new (HTML) approach

So what does this new way of lazy-loading look like? No worries, it's perfectly simple. You just have to add loading="lazy" to your image tag and that's it. 😎



<img src="/path/to/your/image.jpg" loading="lazy" />


Enter fullscreen mode Exit fullscreen mode

With this new loading attribute, you can completely defer the loading of offscreen images (and even iframes in some browsers) to when they enter the viewport. Enough talking, let's see it in action!

The attribute comes with three values:

  • auto - (Default) equal to not including the attribute.
  • lazy - Defer loading of resources until it enters the viewport.
  • eager - Load the resource immediately

What about browser support?

The attribute is supported by almost every popular browser (Chrome, Edge, Opera and Firefox). The implementation for Safari is in progress and almost done. If you need more detailed information on cross-browser support caniuse.com is your friend.

What happens if a browser does not support the attribute?

Browsers that do not support the loading attribute simply ignore it without any side-effects. Fortunately, there is a polyfill at Github available named loading-attribute-polyfill which can be used in those cases.



if ('loading' in HTMLImageElement.prototype) {
    // Cool! The browser supports the loading attribute
} else {
   // Houston... We need a polyfill!
}


Enter fullscreen mode Exit fullscreen mode

Are there any limitations?

Even though it is pretty cool to let the browser do the lazy-loading work, you should be aware of some limitations that come into play when using the attribute:

  • Unlike the Javascript variants, you do not have any influence on the threshold to load the resource. It is part of the browser code and can't be changed for now.
  • The attribute can't be used in combination with CSS background images. Maybe it will come in near future but it is definitely not available now.
  • If printing the webpage is a real usecase for you, then please notice that there is an open bug for the loading attribute.

If you liked this post, please give me a ❤️ or even a 🦄 and feel free to follow me on dev.to. Appreciate it! ✌️

💖 💪 🙅 🚩
pfacklam
Paul Facklam

Posted on February 8, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related