You can preload responsive images, which can let your images load
significantly faster by helping the browser identify the correct image
from a srcset
before it renders the img
tag.
Responsive images overview
Browser Support
Suppose you're browsing the web on a screen that's 300 pixels wide, and the page requests an image 1500 pixels wide. That page has wasted a lot of your mobile data because your screen can't do anything with all that extra resolution. Ideally, the browser would fetch a version of the image that's just a little wider than your screen size, for example, 325 pixels. This ensures a high-resolution image without wasting data, and lets the image load faster.
Responsive images
let browsers fetch different image resources for different devices. If you don't
use an image CDN, save multiple dimensions for each
image and specify them in the srcset
attribute. The w
value tells the
browser the width of each version, so it can choose the appropriate version for
any device:
<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">
Preload overview
Preloading lets you tell the browser about critical resources that you want to load as soon as possible, before they're discovered in HTML. This is especially useful for resources that aren't readily discoverable, such as fonts included in stylesheets, background images, or resources loaded from a script.
<link rel="preload" as="image" href="important.png">
imagesrcset
and imagesizes
The <link>
element uses the imagesrcset
and imagesizes
attributes to
preload responsive images. Use them alongside
<link rel="preload">
, with the srcset
and sizes
syntax used in the
<img>
element.
For example, if you want to preload a responsive image specified with:
<img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">
You can do that by adding the following to your HTML's <head>
:
<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">
This initiates a request using the same resource selection logic that
srcset
and sizes
use.
Use cases
The following are some use cases for preloading responsive images.
Preload dynamically-injected responsive images
Imagine you're dynamically-loading hero images as part of a slideshow, and you know which image will be displayed first. In that case, you probably want to show that image as soon as possible, and not wait for the slideshow script to load it.
You can inspect this issue on a website with a dynamically-loaded image gallery:
- Open this slideshow demo in a new tab.
- Press
Control+Shift+J
(orCommand+Option+J
on Mac) to open DevTools. - Click the Network tab.
- In the Throttling drop-down list, select Fast 3G.
- Disable the Disable cache checkbox.
- Reload the page.
Using preload
here lets the image start loading ahead of time, so it can be
ready to display when the browser needs to display it.
To see the difference that preloading makes, inspect the same dynamically-loaded image gallery but with the first image preloaded by following the steps from the first example.
Preload background images using image-set
If you have different background images for different screen densities, you can
specify them in your CSS with the image-set
syntax. The browser can then
choose which one to display based on the screen's
DPR.
background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);
The problem with CSS background images is that the browser discovers them
only after it has downloaded and processed all the CSS in the page's <head>
.
You can inspect this issue on an example website with a responsive background image.
Responsive image preloading lets you load those images faster.
<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">
Leaving out the href
attribute lets you ensure that browsers that don't
support imagesrcset
on the <link>
element, but do support image-set
in
CSS download the correct source. However, they won't benefit from the preload in
this case.
You can inspect how the previous example behaves with a preloaded responsive background image in the responsive background preload demo.
Practical effects of preloading responsive images
Preloading your responsive images can speed them up in theory, but what does it do in practice?
To answer that I created two copies of a demo PWA shop: one that doesn't preload images, and one that preloads some of them. Because the site lazy loads images using JavaScript, it's likely to benefit from preloading the ones that appear in the initial viewport.
That produced the following results for no preload and for image preload:
- Start Render stayed the same.
- Speed Index improved slightly (273 ms, as images arrive faster don't take up a huge chunk of the pixel area).
- Last Painted Hero improved significantly, by 1.2 seconds.
Preload and <picture>
The Web Performance Working Group is discussing adding a preload equivalent for
srcset
and sizes
, but not the <picture>
element, which handles the "art direction"
use case.
There are still a number of technical issues to sort out for preloading <picture>
,
but in the meantime, there are workarounds:
<picture>
<source srcset="small_cat.jpg" media="(max-width: 400px)">
<source srcset="medium_cat.jpg" media="(max-width: 800px)">
<img src="large_cat.jpg">
</picture>
The <picture>
element's image source selection logic goes over the media
attributes of the <source>
elements in order, finds the first one that
matches, and uses the attached resource.
Because responsive preload has no notion of "order" or "first match", you'll need to translate the breakpoints into something like the following:
<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">
Preload and type
The <picture>
element also supports matching on the first type
, to let you
provide different image formats so the browser can pick the first image format
it supports. This use case isn't supported with preload.
For sites using type matching, we recommend avoiding preload, and instead having
the preload scanner pick up the images from the
<picture>
and <source>
elements instead. This is a best practice anyway,
especially when using Fetch Priority for help prioritizing
the appropriate image.
Effects on Largest Contentful Paint (LCP)
Because images can be Largest Contentful Paint (LCP) candidates, preloading them can improve your website's LCP.
Regardless of whether the image you're preloading is responsive, preloads work best when the image resource isn't discoverable in the initial markup payload. You'll also get more LCP improvement on sites that render markup on the client side than on sites that send complete markup from the server.