mattc.

Lazy Loading Images 2020

Date Published:

View On Medium

Lazy loading is a concept where you only load the images within the viewport of the device the user is in. As the user navigates around the site, images will load in on demand. This makes a massive improvement on the page weight, which then has a domino effect on the load time due to less requests coming in on initial load of the page.

Let’s go through how implementing the current way of lazy loading.

Implementing lazy loading

My go-to plugin is called LazySizes because it is really easy to setup, has multiple add-ons, features that extend the current functionality and it is lightweight. It has a mixture of ways of how to implement the script but in this example I am just loading it from git CDN.

Before implementing lazy loading we have two images, a plain img tag and a responsive image:

When implementing lazy loading for a standalone image it is pretty straight forward. All we need to do is add the lazyload class name to the image and then change the src attribute to data-src and that’s it! With picture elements it is a little different because you need to apply data-srcset to the source elements. Without it, they will load the image in regardless of the src on the image tag.

What do we do to make this SEO friendly?

Google crawls pages and get all of the images on the page to then put them in Google image search. It looks for the src attribute on the image but we have changed that to the data-src attribute for our lazy loading so they no longer able to put the images on image search.

Under the hood, LazySizes does some magic to make this work but as a safety net it is always good practice to provide a no JavaScript fallback.

If no JavaScript is enabled on a browser the user will not be able to see the images as there is a dependency on the images loading via our JavaScript library. So we need to add a fallback to make those images are visible. This is done with a mix of css/html/js, in the example below we:

  • add the no-js class to the html
  • add the css in the page to hide lazyload elements
  • add the JavaScript in which will remove the no-js class
  • finally, provide a noscript tag of the image in its previous lazy loading state

And that that is pretty much it, but we are in 2020 now and surely there is other ways of doing this right? My friend, let me introduce you to the native lazy load…

The future of lazy loading plugins?

Lazy loading has a new kid on the block which is called native lazy loading. Native lazy loading is a feature first released by Google Chrome which allows you to set lazy loading on your image. It is also now supported in the last two versions of Edge which leads to around 63% global coverage across all browsers.

It is really easy to implement, all you have to do is add an attribute on the img called loading and define one of the following as its value:

  • auto — default lazy loading behaviour of the browser which is the same as not including the attribute
  • lazy — defer loading of the resource until it is reached in the viewport
  • eager — load the resource as soon as behaviour regardless of where it sits on the page

Is it time to stop using lazy loading plugins?

I don’t think so, loading attribute only works for images and iframes but does not support background images. It also has a less aggressive threshold for loading images as it loads images in quite far down the page whereas lazysizes has a control to change the threshold for when you want the images to load in.

Can we use both? Absolutely!

We can check for native lazyload support in JavaScript which will then change all the data-src attributes to src attributes if the feature is supported.

If you need lazy loading for background images then it is okay to leave the lazysizes script in the page as if but if you only use it for images then it might be worth loading the script in when the feature is not supported.

Conclusion

In conclusion we still need to be using lazy loading plugins but the new native feature can work along side with these plugins which makes the transition over to native a lot more smoothly.

Resources

Back to blogs