2

Maximally optimizing image loading for the web in 2021

 3 years ago
source link: https://www.industrialempathy.com/posts/image-optimizations/
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.

Maximally optimizing image loading for the web in 2021

6 min read. 58 comments

In this post I'll outline 8 image loading optimization techniques to minimize both the bandwidth used for loading images on the web and the CPU usage for image display. I'll present them in the form of an annotated HTML example to make it easy for folks to reproduce the results. Some of these techniques are more established, while others are somewhat novel. Ideally, your favorite mechanism for publishing web documents (like a CMS, static site generator, or web application framework) implements all of these out-of-the-box. I'll keep a list updated at the end of this posts with technologies that provide all of the optimizations outlined here.

Together the techniques optimize all elements of Google's Core Web Vitals by

View the source of this sample image to see all the techniques in action:

Sample image illustrating the techniques outlined in this post.

Optimization techniques #

Responsive layout #

This is a well understood technique to make an image use the available horizontal space up until its maximum size while retaining the aspect ratio. New in 2020 is that web browsers will reserve the correct vertical space for the image before it loads if the width and height attributes are provided for the img element. This avoids Cumulative Layout Shift (CLS).

<style>
img {
max-width: 100%;
height: auto;
}
</style>
<!-- Providing width and height is more important than ever. -->
<img height="853" width="1280" … />

Lazy rendering #

The second technique is more cutting edge. The new CSS attribute content-visibility: auto instructs the browser to not bother layouting the image until it gets near the screen. This has all kinds of benefits, but the most important one might be that the browser will not bother decoding our blurry placeholder image or the image itself unless it has to, saving CPU.

Update 01/27/2021 contain-intrinsic-size no longer needed #

An earlier version of this post explained how to use contain-intrinsic-size to avoid CLS impact of content-visibility: auto but as of Chromium 88 this is no longer needed for images that provide width and height as explained above. Other browser engines do not yet (01/27/2021) implement content-visibility: auto and would presumably follow Chromium's lead on this special case. So, yaihh, this is much simpler now!

<style>
/* This probably only makes sense for images within the main scrollable area of your page. */
main img {
/* Only render when in viewport */
content-visibility: auto;
}
</style>

AVIF #

AVIF is the most recent image format that has gained adoption in web browsers. It is currently supported in Chromium browsers, and available behind a flag in Firefox. Safari support isn't available yet, but given that Apple is a member of the group that is behind the format, we can expect future support.

AVIF is notable because it very consistently outperforms JPEG in a very significant way. This is different from WebP which doesn't always produce smaller images than JPEG and may actually be a net-loss due to lack of support for progressive loading.

For more info on AVIF encoding and quality settings, check out my dedicated blog post.

To implement progressive enhancement for AVIF, use the picture element.

The actual img element is nested in the picture. This can be quite confusing, because the img is sometimes described as fallback for browsers without picture support but basically the picture element only helps with src selection but has no layout itself. The element that is drawn (and which you style) is the img element.

Until very recently it was relatively difficult to actually encode AVIF images on the server-side, but with the latest version of libraries like sharp it is now trivial.

<picture>
<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.avif 1920w,
/img/Z1s3TKV-1280w.avif 1280w,
/img/Z1s3TKV-640w.avif 640w,
/img/Z1s3TKV-320w.avif 320w
"
type="image/avif"
/>
<!-- snip lots of other stuff -->
<img />
</picture>

Load the right number of pixels #

You might have noticed the srcset and sizes attributes in the snippet above. Using the w selector it tells the browser which URL to use based on the physical pixels that would be used if the image was drawn to the user's device given the width calculated from the sizes attribute (which is a media query expression).

With this the browser will always download the smallest possible image that provides the best image quality for the user. Or it may select a smaller image if, for example, the user has opted into some kind of data-saving mode.

Fallbacks #

Provide more source elements with srcsets for browsers that only support legacy image formats.

<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.webp 1920w,
/img/Z1s3TKV-1280w.webp 1280w,
/img/Z1s3TKV-640w.webp 640w,
/img/Z1s3TKV-320w.webp 320w
"
type="image/webp"
/>
<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.jpg 1920w,
/img/Z1s3TKV-1280w.jpg 1280w,
/img/Z1s3TKV-640w.jpg 640w,
/img/Z1s3TKV-320w.jpg 320w
"
type="image/jpeg"
/>

Caching / Immutable URLs #

Embed a hash of the bytes in the image in the URL of the image. In the examples above I'm doing that with the Z1s3TKV in the image URLs. That way the URL will change if the image changes and respectively you can apply infinite cache expiration for your images. You want your caching headers to look something like this cache-control: public,max-age=31536000,immutable.

immutable is the semantically correct cache-control value, but unfortunately it isn't widely supported in browsers (I'm looking at you, Chrome). max-age=31536000 is the fallback to cache for a year. public is important to allow your CDN to cache the image and deliver it from the edge. But only use that if it is appropriate from a privacy perspective.

Lazy loading #

Adding loading="lazy" to the img instructs the browser to only start fetching the image as it gets closer to the screen and is likely to actually be rendered.

<img loading="lazy" … />

Asynchronous decoding #

Adding decoding="async" to the img gives the browser permission to decode the image off the main thread avoiding user impact of the CPU-time used to decode the image. This should have no discernible downside except that it cannot always be the default for legacy reasons.

<img decoding="async" … />

Blurry placeholder #

A blurry placeholder is an inline image that provides the user some notion of the image that will load eventually without requiring fetching bytes from the network.

Sample blurry placeholder

Some notes on the implementation provided here:

  • It inlines the blurry placeholder as a background-image of the image. This avoids using a second HTML element and it naturally hides the placeholder when the image loads, so that no JavaScript is needed to implement this.
  • It wraps the data URI of the actual image in a data URI of a SVG image. That is done because the blurring of the image is done at the SVG level instead of through a CSS filter. The result is that the blurring is only performed once per image when the SVG is rasterized, instead of on every layout saving CPU.
<img
style="

background-size: cover;
background-image:
url('data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http%3A//www.w3.org/2000/svg\'
xmlns%3Axlink=\'http%3A//www.w3.org/1999/xlink\' viewBox=\'0 0 1280 853\'%3E%3Cfilter id=\'b\' color-interpolation-filters=\'sRGB\'%3E%3CfeGaussianBlur stdDeviation=\'.5\'%3E%3C/feGaussianBlur%3E%3CfeComponentTransfer%3E%3CfeFuncA type=\'discrete\' tableValues=\'1 1\'%3E%3C/feFuncA%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter=\'url(%23b)\' x=\'0\' y=\'0\' height=\'100%25\' width=\'100%25\'
xlink%3Ahref=\'data%3Aimage/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAIAAACepSOSAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAs0lEQVQI1wGoAFf/AImSoJSer5yjs52ktp2luJuluKOpuJefsoCNowB+kKaOm66grL+krsCnsMGrt8m1u8mzt8OVoLIAhJqzjZ2tnLLLnLHJp7fNmpyjqbPCqLrRjqO7AIeUn5ultaWtt56msaSnroZyY4mBgLq7wY6TmwCRfk2Pf1uzm2WulV+xmV6rmGyQfFm3nWSBcEIAfm46jX1FkH5Djn5AmodGo49MopBLlIRBfG8yj/dfjF5frTUAAAAASUVORK5CYII=\'%3E%3C/image%3E%3C/svg%3E');
"

/>

(Optional-ish) JavaScript optimization #

Browsers may feel obliged to rasterize the blurry placeholder even if the image is already loaded. By removing it on image load, we solve that problem. Also, if your images contain transparency, then this is actually not optional as otherwise the placeholder would shine through.

<script>
document.body.addEventListener(
"load",
(e) => {
if (e.target.tagName != "IMG") {
return;
}
// Remove the blurry placeholder.
e.target.style.backgroundImage = "none";
},
/* capture */ true
);
</script>

Tools #

This is a list of known technologies and tools implementing all of these optimizations:

If you know of a technology (can be a combination of multiple "modules" or similar if they work well together) that should be on this list, please ping me.

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.

Comments #

Sara Soueidan said: Maximally optimizing image loading for the web in 2021 by @cramforce
Loads of great #performance tips in there, some I didn’t know of before (like the `decoding` attribute 😯)
Thread

Sebastien Lorber 🇫🇷 said: TIL there's a "decoding" attr in html image in this post from @cramforce🖼 Image

Victor Ribero 🧘🏼‍♂️ said: Learn the different ways to do image optimization to have a great
- Responsive layout
- Lazy rendering
- AVIF
- Load the right number of pixels
- Caching
- Blurry placeholder
- Etc

Chris Heilmann said: 👉🏻 “Maximally optimizing image loading for the web in 2021”
🔗
That's a lot of options. By @cramforce

ScaleDynamics Dev 💻✨ said: Maximally optimizing image loading for the web in 2021 by @cramforce
Read it here 👉
#webperf #webperformance #webdev #webdevelopment #javascript #developer #frontend🖼 Image

Lee Robinson said: 2️⃣ Lazy-load images as they enter the viewport
The browser shouldn't load images a user can't see. To prevent page speed from being penalized, we should load images as they're scrolled into the viewport.
Thread

Zach Leatherman said: For me—I don’t think this is worth it. Not if it has a JS cost.
Maybe only for huge images (not on by default) and definitely *not* animating it.
Either way, @cramforce has a nice No-JS blur-up demo in his blog post
Thread

Marcus Tandler ✰ said: Phenomenal #HowTo article from @cramforce > "Maximally optimizing image loading for the web in 2021"

Jon Kantner said: A helpful list of 8 image optimization techniques to minimize bandwidth and CPU usage

Koray Tuğberk GÜBÜR said: More Google Engineer should write such great guidelines.

Glenn Gabe said: I must have missed this post in late December. I recommend reading this... it's from @cramforce... he's working on the Page Experience Signal at Google, worked on Web Stories, AMP, and more. These techniques can help optimize for all aspects of Core Web Vitals. Enjoy :)

Mattia Astorino said: "Just add an image here, they said..."
Handling images for modern web is something not easy. This is a good overview about how to do it now.

Andrey Markeev said: Good to know. Tells something about the state of web images 😱
I mean, why the heck should it be SO complex to add an image to a website?! 🙄

Ana Travas said: Learn the different ways to do image optimization:
- Responsive layout
- Lazy rendering
- AVIF
- Load the right number of pixels
- Caching
- Blurry placeholder ...
by @cramforce

Arnaud Spanneut said: Nice article from @cramforce about image loading optimization ⚡️
#webperformance #softwaredevelopment

Dan Denney said: Maximally optimizing image loading for the web in 2021
* Some awesome tips in here

Eliacocca said: Wild how much this has changed since 2017 when I made my performance course

Craig Buckler said: Image optimization in 2021
Some cutting-edge techniques here including AVIF, async decoding, content-visibility, and contain-intrinsic-size properties.

Phil Booth said: My, my - how far we've come since the day in 1993 when @pmarca first proposed the <img> tag!
"Maximally optimizing #image loading for the web in 2021":
HT @owenblacker
__
*Some history:
And the actual e-mail:🖼 Image

Adam Marsden said: 3/ 📚 Top Reads
Maximally optimizing image loading for the web in 2021
🔗 (@cramforce)
Legibility in User Interfaces
🔗 (@nitishkmrk)🖼 Image
Thread

Erika Vespa said: All you have to know about image loading optimization techniques for the web
By @cramforce

Reza said: It helps a lot to save money and time for your web application

webmonkey 🦄 said: A great explanation on image optimization for the web 💯

Simon Ihmig said: Hey @cramforce 👋
Many of the improvements in that version were based on your great blog post here:
So thanks for that! 🙏
You asked for a ping when a tool implements all of it, so here it is! 😬
Thread

Anatol Merezhanyi said: "Maximally optimizing image loading for the web in 2021" by @cramforce shares 8 practical techniques for optimizing image loading and decoding (explained as an annotated #HTML example) #design #FrontEnd #webdev

Arnout Hellemans said: Awesome post by @cramforce on image optimizations options in 2021, must read imho for #seo and #webperf tweeps

Inautilo said: Maximally optimizing image loading for the web in 2021 · Established and fresh optimization techniques

Yohan J. Rodríguez said: #Wordpress #Automated | Maximally Optimizing Image Loading for the Web in 2021 <span style="font-size:12px; color:#f78787; text-decoration:none">()

XWP said: Images take up a huge chunk of space on your website, and can ruin your performance. This comprehensive guide will help you optimize your images and keep your site running smoothly. Via @cramforce.
Thread

Simpledev said: Maximally optimizing image loading for the web in 2021 very nice article I didn't know the decoding attribute. Thank you @cramforce

JD from DanylkoWeb said: ☕ *Morning Coffee Link* --
Maximally optimizing image loading for the web in 2021 -🖼 Image

Ben Myers 🦖 said: There is a whole *world* of image optimization I just don't know yet.
Thread

Caspar Hübinger said: Read, bookmark, implement.

Hugh Haworth said: @ryanflorence This looks at source set for image optim

Gianluca Fiorelli wears a 😷. Be like Gianluca said: This ⬇️⬇️⬇️

Kevin Marks said: Wow that's a lot of ceremony around images. I do like that some of them are becoming part of the browser default, but hardcoding pixel widths seems a shame.
Thread

Mike Gifford said: has some great ideas for speeding up web pages. For other ideas worth checking out @SustainableUX & also signing up for @eatwholegrain's #CuriouslyGreen newsletter. I don't think I'd run across #srcsets before.

Craig Dennis 👨‍💻 said: .@cramforce wrote about some techniques to help you optimise image loading
Thread

Jan Rajtoral™ said: .. eight image loading optimization techniques to minimize both the bandwidth used for loading images on the web and the CPU usage for image display ~ Maximally optimizing image loading for the web in 2021🖼 Image

Charles Meaden said: 8 handy image loading techniques to ensure that you're images load really fast

MIND Development And Design said: Images are engaging #content, but they can also slow down your #website. Here are some tips for optimizing image loading on the web:

Phil Wolstenholme said: @maxiorel It's a little trick where the blurred version is set as a background image, so when the main image loads, the bg is hidden. It's based on this:
I'll include a small bit of JS to remove the bg, for anyone who wants to use it with a transparent image.
Thread

Tim Finin said: It's a good time of the year to remember our poor machines. Malte Ubl (@cramforce) describes 8 image loading optimization techniques (some new for 2021) to minimize the bandwidth used for loading images on the Web and CPU usage for image display.

Wayne Kessler said: "Adding loading="lazy" to the img instructs the browser to only start fetching the image as it gets closer to the screen and is likely to actually be rendered."

Mike Harley, Goblin Herder said: Great timing as I’ve been studying this topic and trying to understand it at a deeper level.
...
Maximally optimizing image loading for the web in 2021

Graeme Benzie said: I like the progress bar !

Eric Lee said: Image optimization with almost zero JS 🎉

Digitalworx said: Optimize image loading. Some great tips. #webdesign #webdev

Brian Louis Ramirez said: Great idea to inline a blurry placeholder image to avoid a network request. I'll give it a try for LCP candidates, but I could imagine it won't really help for BTF images.
Thread

The whale said: Maximally optimizing image loading for the web in 2021 - In this post the author will outline 8 image loading optimization techniques to minimize both the bandwidth used... #Front #Image #Optimization by @cramforce

Christoph Siedentop said: Not my area (web) but I always like a good optimization post.

Paul Applegate said: I don't understand it all, but I am following enough smart people on Twitter to soak up some knowledge. Probably. Maybe. Hopefully.

👨‍💻🚀 Matthias Heisterkamp said: @tanoaksam Take a look at this ...

wash your 🙌 and shut your 🤐 said: Good read on the image optimisation techniques for the web:
via @SidebarIO

For Web said: Maximally optimizing image loading for the web in 2021. Malte Ubl shares 8 image loading optimization techniques to minimize both the bandwidth used for loading images and the CPU usage for image display →🖼 Image

Lucio Martinez said: Powerful list of optimisations and possible improvements at the time of rendering an image in web 🚀

James said: A very interesting article by @cramforce (brought to my attention via @css newsletter) about the current state of optimising images on the web.

Edis Golubich said: Something awesome!

Clicking the button will open a new window to compose a tweet. Tweets with a URL to this article may show up as comments on this article.

Published 28 Dec 2020


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK