Illustration by unDraw
Optimise media on the web with next generation formats
Optimise media on the web by serving users with next generation formats like WebP, WebM and AVIF.
While there are a number of techniques out there for optimising images for the web, in this article I will be showing you how to optimise for speed by cutting down the size of image files. Specifically, I will be guiding you through converting your PNG/JPEG/GIF files to a couple of new file extensions that were built for the web. Then we will be adding a fallback to our converted files to provide support for browsers that don't support these extensions.
This article is divided into three sections and for each one of them we will be going through the 3-step process of installing a library, converting and adding the new files to our project:
- WebP (
.webp) for images
- WebM (
.webm) for animated graphics
- AVIF (
.avif) for images
Because when it comes to web media, size matters!
WebP for images#
Warning: WebP although has a good browser support is not yet fully supported so make sure you provide a fallback for older browsers. We will be covering the fallback part further down👇
The WebP team at Google offers a library called
libwebp on Mac, Windows and Linux which contains a number of tools for converting images, GIFs and videos to WebP format. For this article I will only be covering the
cwebp tool from this library. You can check out all of the tools available in their documentation here.
So let’s begin the process for optimising our images on the web.
WebP step 1#
Download the right
libwebp library for your machine and unzip it.
Note: You may need to add some symlinks to the bin files in order to access them from anywhere inside your terminal.
If on macOS and getting security popups follow this guide on your own discretion!
WebP step 2#
Now that we have the tools ready let’s put them to use. Here are a few examples using the
cwebp tool to convert PNG/JPEG images to WebP format:
cwebp picture.png -o picture.webp cwebp -q 50 -lossless picture.png -o picture_lossless.webp cwebp -q 100 picture_with_alpha.png -o picture_with_alpha.webp
-qsets the quality which can be
0–100. Default is
-losslessencodes the image without any loss
-exactpreserves the RGB values in a transparent area. Off by default
Warning: Do not replace your old files!! Add the converted files to your project directory while keeping your old files as well. They will be needed for the next step. Bear with me.
WebP step 3#
Now the annoying but important part of our optimisation technique. Since IE and some versions of Safari do not support it we will need to add a fallback JPEG or PNG image which will be downloaded instead of the WebP for these browsers.
<picture> <source srcset="/img/picture.webp" type="image/webp"> <img src="/img/picture.jpg" alt="Image description" type="image/jpeg"> </picture>
WebM for animated graphics#
WebM is a sister project to WebP and is also developed by Google. As you may have guessed, it is developed for serving video and audio over the web.
If you are serving GIF files somewhere in your website you should definitely consider converting them to WebM or MP4 video formats and then using the HTML5
<video> tag to display them in loop. Wait. What? A
<video> tag 😕?
Yep that’s right! I will be now showing you an easy way to bend the laws of the web and serve highly optimised image animations in a video file format 😎.
Best practise: By using the following method, I can cut down almost 95% of the original GIF file size using lossy compression.
WebM step 1#
First and foremost we will have to convert our GIF files to both WebM and MP4 file formats. We will need the MP4 format as a fallback to WebM since it is not fully supported across all browsers. For this we will be using one of my all time favourite tools, ezgif.com:
Note: I also created a dedicated tool for the job at gif2video.com. It uses ffmpeg within a Node server in the background. If you are curious you can check out the code on Github and spin up your own server if you prefer (mine is on the free tier 😊 ).
WebM step 2#
In order to use these newly converted files, we will use the HTML5
<video> tag and tailor it to our needs. Finally, the video files should be displayed as if they were endless GIF animations.
All we need to do really is to add the following attributes onto our
autoplaystarts the video once it is loaded
loopplays the video in a loop
mutedmakes sure that
autoplayis enabled for browsers that require it
playsinlineprevents our video from going full-screen
<video loop muted autoplay playsinline> <source src="animation.webm" type="video/webm"> </video>
WebM step 3#
Now we don’t necessarily need to add our GIF file as a fallback, but instead we will be using our MP4 file we previously created, since it is well supported and is smaller in size than GIF normally.
Adding MP4 as a fallback to the WebM video file:
<video loop muted autoplay playsinline> <source src="animation.webm" type="video/webm"> <source src="animation.mp4" type="video/mp4"> </video>
Now you might be asking yourself "if WebM is so important to you why do you use GIFs in your blog?" and you will be catching me off guard 😐. The reason that I don't serve WebM yet is because I use Sanity as my CMS and it doesn't yet support video files where my images go but I will definitely figure something out with Sanity's File type at some point.
AVIF is another image format created by the Alliance for Open Media and it has even better compression than WebP. Hooray! 🎉
You can read more about a study from Netflix on the improvements of the AVIF compression at Netflix Tech Blog on Medium. If you didn't have enough here is another study on comparing WebP to AVIF!
If you would like to start right on and use AVIF, for the browsers that support it, with progressive enhancement you can encode and decode AVIF images by using the libavif library from AOMedia.
You can then add any AVIF image on the very top of the browsers choices inside a
<picture> element, similar to WebP:
<picture> <source srcset="/img/picture.avif" type="image/avif"> <source srcset="/img/picture.webp" type="image/webp"> <img src="/img/picture.jpg" alt="Image description" type="image/jpeg"> </picture>
I hope you found this technique useful and can use it as well to slim down your images on the web. If there are any other techniques you would prefer using instead or if any of this didn’t completely cover your needs, please don't hesitate to get in touch.
Cheers and have a good one!