14 November 2019
The new native lazy loading for images and iframes in Chromium-based browsers
Check out my previous article on lazy loading if you haven’t already. Otherwise, let’s get to native lazy loading in Chromium-based browsers.
loading=”lazy” attribute to
iframe tags that you want to load on demand. The browser will load these when users scroll near the element.
And here’s how it works:
Now, how did we get there?
Graphic assets are often the most significant part of the data required to display a page. Completely understandable from the UX/UI point of view though – they make your website look more appealing to the users. While these assets are needed, some of them may be off-screen. That makes it possible to defer loading them to the time when they are actually required – when a user scrolls down and is near seeing them. That operation of deferring loading resources is called lazy loading (or “on-demand” loading).
Now we have a new option – a native implementation that just works and can be used easily by developers right at the time of adding new elements.
And by a fact that’s just an attribute, it can be used with every frontend framework. That’s something I’ve been waiting for.
Read more: A guide to Svelte – what can the rising frontend framework do for you?
The full specification can be found in a proposal pull request on GitHub and I strongly encourage you to read the discussion there in order to see how it looks like to propose a new attribute to a living specification and what you need to think about. However, it’s not required to get to know how the
loading attribute works, and we can just jump straight into values we have available:
lazy– flags asset as a good candidate to be loaded lazily,
eager– forces asset to load straight away disabling lazy-loading,
auto(or value not set) – leaves the decision to a browser.
What about scrolling?
Scroll distance threshold
All images and iframes above the fold (being visible without scrolling) load normally, others are loaded when the user scrolls near them. The distance when elements should begin loading is dynamic and depends on:
- Connection type (e.g. 3g, 4g, unknown),
- Type of resource (image or iframe),
- Whether Lite Mode is enabled in Chrome for Android.
Currently, these values are hardcoded in Chromium’s source and can be overridden only using command line arguments. It may seem like a big issue of the native implementation but actually, it has one substantial advantage – it depends on the effective connection type of user’s device. It would require a lot of work to detect it correctly and we can assume that the values provided by authors of that feature are calculated correctly, so we don’t need to worry about it.
Note: Chrome 77 allows to experiment how different connection types are affecting distance threshold by setting network throttling in DevTools.
To make the native lazy loading work, you need to add a single attribute –
loading="lazy" to an
img element. However, you may want to prevent browser reflow when the image is loaded by adding dimensions to it (
height attributes) or using styles.
iframe elements work slightly different than images. Chrome firstly checks whether the element is hidden (is/isn’t a good candidate to be lazily loaded). Chrome considers the element as hidden when:
- the element’s width and height are 4px or smaller,
visibility: hidden;is set,
- the element is off-screen using negative positioning values.
Iframes that aren’t labeled as hidden load when a user scrolls near them (like images).
What about the
Lazily loaded image and iframe element’s
onload events are triggered – as you might expect – when data is completely loaded. So when the element is lazily loaded,
onload fires as a user scrolls near it, and the data is fetched.
onload event works a little bit differently. Traditionally, the event has been fired when all images and iframes were already loaded. With lazy loading, the document doesn’t wait for deferred, off-screen elements to be loaded before triggering the event.
Lazy loading browser support
Currently, the native lazy loading feature has shipped with Chrome 76 stable release and is available in all Chrome 76+ based browsers. By the time of writing this article, I was able to use native lazy loading in Chrome, Opera, and Microsoft Edge Beta. There’s also an open implementation ticket for Firefox.
You can easily detect if native lazy loading is present by checking the
loading property – it’s defined in prototypes of
Here are some examples of using the new
loading attribute that show how easy it is to actually use the feature.
What’s the future of native lazy loading?
Native Lazy Loading is a new proposal that might become a standard one day. Thankfully it’s been implemented in Chrome, and there are easy ways to polyfill it. I encourage you to play with the new