DEV Community

loading...

Native lazy loading is landed in Chrome πŸ”₯😍πŸ”₯

yashints profile image Yaser Adel Mehraban Originally published at yashints.dev ・4 min read

Lazy loading resources is one of the important parts of web performance tuning, simply because offscreen resources can add a lot of weight to your page if loaded eagerly.

Intro

I've gone through many tips and tricks in my image optimisation article which is one of the series I've done on web performance. However, when it comes to lazy loading, I mentioned that you have two options:

  • Use data-src attribute on <img> tag and hook into either of scroll, resize, or orientationChange to figure out when to replace the data-src with src to make the call.
  • Use IntersectionObserver API to asynchronously observe the changes and make the call when the item in is the viewport.

The good news is, from Chrome 76, you can use the loading attribute of an image tag to tell the browser how to load the image.

In fact it's so simple that you won't believe it 🀯:

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

I've created a demo to show you how it works, look closely on the network tab.

Lazy loading images natively in Chorme

Here is a CodePen which contains the code πŸ‘‡πŸ½:

.

I've just used below bash script to hack together the HTML πŸ€·πŸ½β€β™‚οΈ.

for i in {400..499}; 
> do echo "<img loading='lazy' 
src='https://placedog.net/${i}/${i}' height='${i}' width='${i}' />"; 
> done
Enter fullscreen mode Exit fullscreen mode

About the attribute

Currently the images are fetched with different priority in Chrome, the ones which are not in the viewport have less priority. But they're fetched as soon as possible regardless.

With this new loading attribute, you can completely defer the loading of offscreen images (and iframes) to when they're reached by scrolling:

<img src="../path/to/image.jpg" loading="lazy">
<iframe src="https://placedog.net" loading="lazy"></iframe>
Enter fullscreen mode Exit fullscreen mode

You can use three values with this attribute:

  • auto: Default behaviour of the browser, equal to not including the attribute.
  • lazy: Defer loading of resources until it reaches a calculated distance from viewport.
  • eager: Load the resource immediately

My Chrome version is 76.0.3809.100 as of writing this post, but if you have any of the previous version below 76, you can activate this using flags:

  • For images πŸ‘‰πŸ½ chrome://flags/#enable-lazy-image-loading
  • For iframes πŸ‘‰πŸ½ chrome://flags/#enable-lazy-frame-loading

Feature detection

If you want to use this attribute today, you can use below code to feature detect it and have a polyfill in place such as loading-attribute-polyfill.

if ('loading' in HTMLImageElement.prototype === true) {
  // use the attribute
} else {
  // use polyfill
}
Enter fullscreen mode Exit fullscreen mode

Prevent content reflow

Since the images are lazy loaded, if you haven't set width and height for your image, the content might reflow when the image is loaded and fill its place. To prevent that to happen, simply set the required values on the image tag by either style or directly using width and height attributes:

<img src="../path/to/image.jpg" 
loading="lazy" width="200" height="200">

<img src="../path/to/image.jpg" 
loading="lazy" style="height:200px; width:200px;">
Enter fullscreen mode Exit fullscreen mode

iframe loading

The same behaviour is applied to iframe when it's used with loading attribute. However, there are times when an iframe is hidden for analytics purposes. Examples are they are very small (less than 4px in width and height), or they have display:none or visibility: hidden applied to them, or simply is offscreen using negative margin.

In these cases it won't get lazy loaded even if you have used the attribute.

What's the catch

There are few points you have to consider when using lazy loading in general. Plus there are a few things you can't do with the loading attribute as of now.

Can't do

  • You can't change the threshold to load the resource for now since it's been hard coded in the source.
  • This can't be used with CSS' background image for now

Catches

  • This might affect the third party ads since they will be lazy loaded too
  • There will be side effect when printing πŸ˜‰, as in the lazy loaded resources won't be printed. However, there is an open issue you can follow.

What about other browsers?

For now, Chrome is the only browser supporting this feature. Although there is an open bug for Firefox and nothing for Edge and IE.

Happy lazy loading everybody and make sure not to miss the catches πŸ‘‹πŸ½.

Discussion (8)

pic
Editor guide
Collapse
ben profile image
Ben Halpern

Great writeup!

auto: Default behaviour of the browser, equal to not including the attribute.

I've had trouble being sure about this as written in different places. Is the auto value going to be as if this feature never existed or does it mean that the browser will choose the behavior and things still might be "lazier" than they had been in the past?

...does that question make sense?

I really really like this. DEV implemented this feature as soon as we possibly could.

I just did a quick pass to get it in some images, still need to go through more of the site and implement this in more places, especially with iframe embeds.

Collapse
yashints profile image
Yaser Adel Mehraban Author

Thanks Ben, the auto means you are delegating the responsibility to the browser. As I mentioned, each browsers has a different way of dealing with depriotising offscreen resources, so they will use it. Also if a browser doesn't have any strategy (which is possible) then it's equal to eager

Collapse
link2twenty profile image
Andrew Bone • Edited

Auto, for now, will be the same as eager but the browser makers will get to choose.

Indicates a preference for the user agent to determine the fetching strategy (the default)

github.com/whatwg/html/pull/3752/f...

Collapse
abraham profile image
Abraham Williams

'loading' in HTMLImageElement.prototype should always return true or false so you shouldn't need to then compare the result to true like in 'loading' in HTMLImageElement.prototype === true.

Collapse
dacko_m profile image
Dragan Malinović

Does this work with divs or other elements that have overflow:auto? Or just with scrolling the body element?

Or for example modals that are in dom and have images with lazy loading attribute, but are positioned outside the view and waiting to be shown with top:0 for example?

Collapse
yashints profile image
Yaser Adel Mehraban Author

Yes, for divs with overflow auto it will work fine. However, I am not too sure about Modals, have a look at the Distance Threshold to see how close to coming into viewport should the element be to trigger the request.

PS: If you gave it a shot for Modals, let me know and I'll update the article, that's a good one. I will try to test it myself later this week too

Collapse
rotemgrim profile image
Rotem Grimberg

what about images in backgrounds ?

Collapse
yashints profile image
Yaser Adel Mehraban Author

If you mean with CSS, that's not there yet as mentioned in the article