

Native image lazy-loading for the web
source link: https://www.tuicool.com/articles/hit/3Mnqy2N
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In this post, we'll look at the new
loading
attribute which brings native <img>
and <iframe>
lazy-loading to the web!. For the curious, here's a sneak preview of it in action:
<img src="celebration.jpg" loading="lazy" alt="..." /> <iframe src="video-player.html" loading="lazy"></iframe>
We are hoping to ship support for loading
in Chrome 75
and are working on a deep-dive of the feature we'll publish soon. Until then, let's dive into how loading
works.
Introduction
Web pages often contain a large number of images, which contribute to data-usage, page-bloat and how fast a page can load. Many of these images are offscreen, requiring a user to scroll in order to view them.
Historically, to limit the impact offscreen images have on page load times, developers have needed to use a JavaScript library (like LazySizes ) in order to defer fetching these images until a user scrolls near them.

What if the browser could avoid loading these offscreen images for you? This would help content in the view-port load quicker, reduce overall network data usage and on lower-end devices, reduce memory usage. Well, I'm happy to share that this will soon be possible with the new loading
attribute for images and iframes.
The loading
attribute
The loading
attribute allows a browser to defer loading offscreen images and iframes until users scroll near them. loading
supports three values:
-
lazy
: is a good candidate for lazy loading. -
eager
: is not a good candidate for lazy loading. Load right away. -
auto
: browser will determine whether or not to lazily load.
Not specifying the attribute at all will have the same impact as setting loading=auto
.
Examples
The loading
attribute works on <img>
(including with srcset
and inside <picture>
) as well as on <iframe>
:
<!-- Lazy-load an offscreen image when the user scrolls near it --> <img src="unicorn.jpg" loading="lazy" alt=".."/> <!-- Load an image right away instead of lazy-loading --> <img src="unicorn.jpg" loading="eager" alt=".."/> <!-- Browser decides whether or not to lazy-load the image --> <img src="unicorn.jpg" loading="auto" alt=".."/> <!-- Lazy-load images in <picture>. <img> is the one driving image loading so <picture> and srcset fall off of that --> <picture> <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" loading="lazy"> </picture> <!-- Lazy-load an image that has srcset specified --> <img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf" loading="lazy"> <!-- Lazy-load an offscreen iframe when the user scrolls near it --> <iframe src="video-player.html" loading="lazy"></iframe>
The exact heuristics for "when the user scrolls near" is left up to the browser. In general, our hope is that browsers will start fetching deferred images and iframe content a little before it comes into the viewport. This will increase the change the image or iframe is done loading by the time the user has scrolled to them.
Note: I suggested
we name this the loading
attribute as it's naming aligns closer with the
decoding
attribute. Previous proposals, such as the lazyload
attribute didn't make it as we needed to support multiple values ( lazy
, eager
and auto
).
Feature detection
We've kept in mind the importance of being able to fetch and apply a JavaScript library for lazy-loading (for the cross-browser support). Support for loading
can be feature-detected as follows:
<script> if ('loading' in HTMLImageElement.prototype) { // Browser supports `loading`.. } else { // Fetch and apply a polyfill/JavaScript library // for lazy-loading instead. } </script>
Note: You can also use loading
as a progressive enhancement. Browsers that support the attribute can get the new lazy-loading behavior with loading=lazy
and those that don't will still have images load.
Cross-browser image lazy-loading
If cross-browser support for lazy-loading images is important, it's not enough to just feature-detect and lazy-load a library if you're using <img src=unicorn.jpg loading=lazy />
in the markup.
The markup needs to use something like <img data-src=unicorn.jpg />
(rather than src
, srcset
or <source>
) to avoid triggering an eager load in browsers that don't support the new attribute. JavaScript can be used to change those attributes to the proper ones if loading
is supported and load a library if not.
Below is an example of what this could look like.
-
In-viewport / above-the-fold images are regular
<img>
tags. Adata-src
would defeat the preload scanner so we want to avoid it for everything likely to be in the viewport. -
We use
data-src
on images to avoid an eager load in unsupported browsers. Ifloading
is supported, we swapdata-src
forsrc
. -
If
loading
is not supported, we load a fallback (LazySizes) and initiate it. Here, we useclass=lazyload
as a way to indicate to LazySizes images we want to be lazily-loaded.
<!-- Let's load this in-viewport image normally --> <img src="hero.jpg" alt=".."/> <!-- Let's lazy-load the rest of these images --> <img data-src="unicorn.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="cats.jpg" loading="lazy" alt=".." class="lazyload"/> <img data-src="dogs.jpg" loading="lazy" alt=".." class="lazyload"/> <script> (async () => { const images = document.querySelectorAll("img.lazyload"); if ('loading' in HTMLImageElement.prototype) { images.forEach(img => { img.src = img.dataset.src; }); } else { // Dynamically import the LazySizes library const lazySizesLib = await import('/lazysizes.min.js'); // Initiate LazySizes (reads data-src & class=lazyload) lazySizes.init(); // lazySizes works off a global. } })(); </script>
Extra notes
-
Try today
: Go to chrome://flags and turn on both the "Enable lazy frame loading" and "Enable lazy image loading" flags then restart Chrome. We are updating the implementation from the old attribute name
load
toloading
over the coming weeks. -
DevTools
: An implementation detail of
loading
in Chrome is that it fetches the first 2KB of images on page-load. It fetches the rest of the image byes when the user is about to see them. This can result in (1) double fetches to 'appear' in the DevTools Network panel and (2) Resource Timing to have 2 requests for each image. -
Client Hint
: Rather than waiting for client-side feature detection to complete, it could be interesting if this check could be done as a HTTP request header. A client hint for conveying
loading
preferences is being considered but is not yet a 'thing'.
Wrapping up
Give <img loading>
a spin and let us know what you think. I'm particularly interested in how folks find the cross-browser story and whether there are any edge-cases we've missed.
References
With thanks to Simon Pieters and Yoav Weiss for their feedback. A large thanks to Ben Greenstein, Scott Little, Raj T and Houssein Djirdeh for their work on LazyLoad.
Recommend
-
84
Vue Lazy Image Loading Vue progressive image and background loading plugin. Installation npm install vue-lazy-image-loading Usage import Vue from 'vue' import VueLa...
-
47
To explore how to add lazy loading functionality to an Angular app, this article will go through the process of building a relatively small application called Tour of Thrones .
-
39
Introduction In this post, we are going to look at how lazy loading works on the web. We will cover the native lazy loading API — how lazy loading is implemented, the importance and advantages of lazy loading,...
-
15
java-version.com: What's new in Java 16? 15? Keep up to date! JPA: lazy loading for lazy developers, the performance issue...
-
14
An argument against lazy loadingMonday, February 25th 2019Opinion: Most of the time, I really dislike using websites that lazy load images.(Yeah, this post is full of my opinions. Yours may differ. That's...
-
25
[Kotlin] Lazy Loading – Android You can find several benefits of using lazy loading in your application. Lazy loading will result in faster startup due to loading is deferred when variable is accessed. This is very usefu...
-
9
Natively lazy-loading Facebook social plugins July 24th, 2020. Tagged: facebook,
-
9
203557 – Determine viewport distances for lazy image loading WebKit Bugzilla Bug 203557: Determine viewport distances for lazy image loading ...
-
9
Blazor Lazy Loading and Dependency Injection Many applications have functionality that is used infrequently. So why should...
-
13
Closed Bug 1542784 (lazyload) Opened 2 years ago Closed 10 months a...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK