Lazy load images with zero Javascript

There are so many posts about lazy loading images, I will bring nothing new to the table. But if you haven’t considered lazy loading yet, here are 3 quick and easy techniques to make web pages faster.

Why

I understand that there are websites that will have lots of images by their nature. But I can’t believe that there are websites made by tech companies that load 5MB-10MB of images, just because it’s easier / faster / cheaper to develop that way.

As an example, initial home page load:

  1. my favorite ice cream 10.3MB of images
  2. mango shop 6MB of images + 4.5MB video
  3. mizuno 7.7MB of images (4.3MB on mobile)
  4. vizio 9.3MB of images (4.7MB on mobile)
  5. sony 8.4MB of images

If user visits page over 3/4g connection you are literally waisting their money.
People do scroll, but majority of the people will never see all those pictures down on the bottom of the page.

Technique #1

We add event listener, for example scroll and resize. Throttle event handler so we are not running on main thread too much. For each lazy image calculate position and check if image is inside viewport. If it’s inside viewport load image. Boring… but it works in every browser.

Demo:

Technique #2

We can use Intersection Observer. We create observer and subscribe to it. Then we go idle and wait. When image hit intersection area or document viewport we will run function. If there is intersection, we load image, done, easy.

Here is a snippet:

If root is null, it will default to document’s viewport. I’m using rootMargin to increase area of intersection in order to load images little bit before they hit document viewport. 
There is another option — threshold(s) which defines intersection ratios. When some amount of ratio is reached our intersection handler will be called.

Technique #lookMaNoJS

Starting from Chrome 70, native lazy loading images are enabled behind a flag. Enable this feature:

chrome://flags/#enable-lazy-image-loading

All we need to do is to give a browser a hint. When image enter document viewport and becomes visible, browser will load it. No JS, zero JS, nothing, only HTML attribute.

By lazy loading images (and all other resources) that are not initially needed, we will download fewer KB, page will load faster. Faster page load => better user experience. In the end nobody likes to wait.

Apart from lazy loading images, we should also optimize our resources and use appropriate file types.

Conclusion

Can we use native lazy load now? No, it is not production ready, it’s only Chrome and it’s hidden behind flag. IntersectionObserver can be used, but it is not supported by Safari and IE.

You can always choose some library like lozad.js, yall.js, lazysizes …
There are also techniques like lqip/sqip for image placeholders. Use them wisely and make web fast.

It’s always cool to see how web is improving day by day.