Maximally optimizing image loading for the web in 2021
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 commentsIn 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
- Minimizing the Largest Contentful Paint (LCP) through reducing bytes, caching, and lazy loading.
- Keeping Cumulative Layout Shift (CLS) to zero.
- Reducing First Input Delay(FID) through reduced (main-thread) CPU usage.
View the source of this sample image to see all the techniques in action:
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 srcset
s 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.
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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK