How to fake Progressive WebP Images
WebP is the hip new image format on the scene. It offers unrivalled image compression at superior visual quality. But, in my opinion, it is deficient compared to JPG in one significant aspect. It doesn't have a progressive mode.
Progressive mode is useful because it can quickly load a low resolution preview of an image, and then gradually improve its quality.
WebP, by contrast, just loads up the full image line by line. That's can be annoying on a slow connection.
What if we could change that? Here's a quick-and-dirty hack. This is a 5472x3080 image which has been compressed down to "zero" quality on WebP and resized to 640x360. It is less than 5KB.

The original image is 400 KB as a WebP and 1.6MB as a JPG.
There are lots of techniques to load low-res images before the main image loads.
We're going old-skool. Basic HTML + CSS.
<img
width=5472
height=3080
alt="Close up of a Raspberry Pi circuit board."
style="background-image: url('Small.webp');"
src="Big.webp"
/>
This sets the background of the image to the low-resolution, low quality version. As the high-resolution image loads, it gradually replaces the image in the background.
There are a few more refinements we could make to this:
<img
width=5472
height=3080
alt="Close up of a Raspberry Pi circuit board."
style="background-color: #0f0;
background-image: url('Small.webp');"
loading="lazy"
src="Big.webp"
/>
This sets the background-color
to the dominant colour of the image. That way, even before the background image has loaded, you get something to fill the gap. Because we've set loading="lazy"
the massive image won't be downloaded until the img
scrolls into view.
We can even go a step further. Let's reduce the image down to a thumbnail of 160x90. That takes us down to a ludicrously small 564 Bytes.
Which makes it small enough to stick directly in the HTML once we encode it in Base64:
background-image: url("data:image/webp;base64,UklGRiwCAABXRUJQVlA4ICACAACQEwCdASqgAFoAP/3+/3+/vLYyPv+8A/A/iWYIkCfrS2sOTiSUArLU15JWpmwHGTJDQ+i/y0UfRMWET8I422NGGsABPAdIKWnTFvlfPnla/wC0DPVYABJxuECkmqWUZwViSm1vqzvPgAnG+vioXrwz0V3Zx+c/znFFJvKBpH5SceJwmAUi8+8SRjzQvyc/qv3DKe3KfEYnXA+5aEBypmacRUvrvgAA+OUzEDYgEioYgJQRm/l9OIIl60M80PJW00cW6fX1fNpB/L4udWsUF5v6gOR6fB//5/0zuirXi2Z2GoqpVh3aeUDEdVThFtQOZStD/ulvCFO54uEqPVZlD63ukgBgt5Q5KA15Nse9lu4E+4XliSgao9azVod9zUr/XELtUpd2CLSyImxIXq3rRNGthLv0jePmYvlqijrhFxgMsdVer/GmM0C6xEyTC53yBQ+aGJlg/iqxrU5uwNjGNi3Or75QpJVdWW0lEyZlOsIiRsCZ+jTXsDMmgzkB4uaiiQASLl4TIYpK587PmaLb29WRF3hxpAtjR4TPDHne3iY6aBfYZhvMo1N41AMMKe7BLZg3w8LCQ2RHRHnkhgYsdtLL2jSFFpP8JgVtwLZ/KtKa6P7VaHm7aY7aT0UWyEwXPnUbZwo5a4yuK1H+P7YJqLj8yjuKSJZACY6z+6RgRxeoSyytYvQiopOOlc4f1Mdoy2WgfE3HR6Ap5jJiPryYLQAA")
Of course, you don't have to go down to quite this extreme level - choose some settings which make sense for you and your media.
To summarise:
- Scale the image down
- Reduce its quality
- Set it as the background to the
img
element
Endnote
I wasn't involved with the development of WebP - but it seems bizarre to me that it doesn't contain a "thumbnail mode". On that ½ MB photo, adding a couple of KB doesn't seem like a huge overhead.
Similarly, the experimental AVIF also lacks progressive / thumbnail support.
Anyone know what the reason is?
Dragon Cotterill says:
Networks are getting faster and more reliable these days and you have already proved that there are alternatives to loading full size images. So why is there the need for adding thumbnails to large images – since you’re going to be downloading these images anyway? Thumbnails have their uses, but I don’t think they should be included in the bigger picture. If you need to have them, then they should be a separate image and loaded appropriately.
I think that having them as part of the main image is for the lazy. If you need them, then code them. If you don’t, then they’re not needed anywhere.
The reality is, data size expands to fill the available bandwidth.
Take a look at HLS and MPEG-DASH - they provide multiple resolution streams because they know that their audience sometimes has limited speed.
Dragon Cotterill says:
So why do we need thumbnails inside large files? Yes the network is the bottleneck and weak link. If it's there, then use it. If it's not then separate thumbnails or data:image URLs help tremendously. I'm afraid you won't convince me that having thumbnails in large files is a benefit. I just don't see the point.
Yes, the photos that I take are huge, but when I copy them off my phone I run a simple script to convert them into something useable.
for file in *.jpg
do
convert $file -resize 640x640 "${file%.jpg}_small.jpg"
convert $file -thumbnail 100x100 "${file%.jpg}_thumb.jpg"
done
When they're like this, it's much easier to code for them. Thumbnails as separate files just work. Easier on the bandwidth for when you're on a packed train. After all, once you've started downloading that huge 20Mb image, it's not like it's going to stop unless you switch to a new page.
Spike says:
Twenty years ago websites used to include low-resolution monochrome .gif thumbnails for images. Logic being that the thumbnails would download first and fill in the hole whilst the high-resolution jpg was sorting itself out.
Gave user on slow dial-up an idea of what the page was without downloading all the graphics.
Looks like we have come around full circle :)
Quentin says:
Though that does, I admit, make them very quick to load :-)
Quentin says:
Q
Nate says:
Nate says:
https://twitter.com/jensimmons/status/1275171897244823553