Lazy load images with zero Javascript

Filip Vitas
Dec 4, 2018 · 3 min read
Image for post
Image for post

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.

Image for post
Image for post

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.

Image for post
Image for post

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:

Image for post
Image for post

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 75+, native lazy loading images are enabled behind a flag. Enable this feature:

chrome://flags/#enable-lazy-image-loading
Image for post
Image for post

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.

Image for post
Image for post

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 optimize our resources and use appropriate file types.

Conclusion

Can we use native lazy load now? No, it’s only Chrome and it’s hidden behind a flag. Hopefully it will hit production soon. IntersectionObserver can be used and it is not supported only by 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 faster.

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

Image for post
Image for post

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store