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:
- my favorite ice cream 10.3MB of images
- mango shop 6MB of images + 4.5MB video
- mizuno 7.7MB of images (4.3MB on mobile)
- vizio 9.3MB of images (4.7MB on mobile)
- 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 75+, 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 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.