How To Use Video Formats for Animated Content [7 Steps]
Despite the popularity of animated GIFs on the web, they're often humongous in file size and slow to load. Because of this, Lighthouse and PageSpeed Insights audits will flag any animated GIF that's over 100 KiB with the warning message "Use video formats for animated content."
What's the solution?
- Replace all animated GIFs with optimized videos.
- Never use animated GIFs again.
In this post, I'll show you how to cut the size of a 2.5 MB GIF down to a 69 KB video that also improves load and Largest Contentful Paint (LCP) times.
Why does this matter?
Animated GIFs are usually much bigger than videos, which can result in the following:
- Longer load times
- Less bandwidth to download other assets on the page
- More cellular data that mobile users pay for
- Slower LCP
How do you fix this? Let's run through an example.
Step 1: Measure the baseline GIF
Let's start with an animated GIF from this demo page. It has a Homer Simpson animated GIF above the fold. There's nothing else that captures embarrassment and awkwardness in one easy-to-use image. What's not to love?
Unfortunately, PageSpeed Insights doesn't find it amusing.
Let's see how it fares with WebPageTest using the following settings:
- Test Location: Virginia, EC2
- Browser: Chrome on emulated Motorola G (gen 4)
- Connection: 4G (9 Mbps, 170ms RTT)
- Number of Tests to Run: 9
The baseline results show:
- LCP: 1.3 seconds*
- Page Weight: 2,442 KB
- Load time: 3.616 seconds
Step 2: Convert to MP4 and WebM video formats
Next, let's convert the animated GIF to a video. But which format should you pick? MP4 has the best browser support, but the less supported WebM format usually results in smaller file sizes.
Format | Browser support |
---|---|
MP4 | > 96.7% (see caniuse) |
WebM | > 95.8% (see caniuse) |
You'll need to decide whether only serving WebM offers enough browser support for your audience. Or you can offer both formats and let the browser decide — that's the approach we'll take in this guide.
Option 1: Use FFmpeg
FFmpeg is a popular command-line tool for converting video. To convert the GIF to MP4, use the following command:
And to convert to WebM:
The preceding commands decrease the file size by 95% for MP4 and by 97% for WebM.
GIF (KB) | MP4 (KB) | WebM (KB) |
---|---|---|
2.5 MB | 122 KB | 80 KB |
If you only have a few videos on your site, you can get great results by manually converting GIFs with the preceding commands. But I recommend using automation for anything more than that.
Option 2: Use an image CDN
Because video and image optimization can be a pain at scale, I prefer to delegate these responsibilities to an image CDN service like Cloudinary. Although image CDNs are typically not free, they can save a lot of hassle with media management and produce great results.
After uploading the image to Cloudinary, you can dynamically convert
it to MP4 by replacing the .gif
file extension with .mp4
, making
sure to replace the <cloud_name>
and <file_name>
placeholders with
your respective Cloudinary info:
Similarly, use the .webm
extension in the URL to convert to WebM:
By converting the GIF to video with Cloudinary, the file size reduces by 96% when converted to MP4 and by over 97% when converted to WebM.
GIF (KB) | MP4 (KB) | WebM (KB) |
---|---|---|
2.5 MB | 88 KB | 71 KB |
Step 3: Replace the img
element with a video
element
Instead of using the <img>
element to serve a GIF, replace it with
the <video>
element, which can serve different formats via the
source element.
The source
elements allow the browser to serve the WebM format if it
supports it. If it doesn't, it will fall back to MP4.
GIF offers the ability to autoplay, loop, and play silently, which you
can replicate with the autoplay
, loop
, and muted
attributes for
video:
The inline style
attribute expands the video to the width of the
content, while the playsinline
attribute is needed on iOS to prevent
the video from entering fullscreen mode.
After doing this, the video looks nearly identical to the original GIF, but with one jarring problem — after the video loads, it shifts the text down, resulting in a Cumulative Layout Shift (CLS):
The browser doesn't know the video's aspect ratio until after it has loaded, which causes the layout shift. What can you do about this?
Step 4: Add aspect-ratio CSS
Unlike the <img>
element, you can't add width
and height
attributes to the video to let the browser figure out the aspect
ratio. That should work, but it's
broken. To get
around this, you can use the
aspect-ratio
CSS property instead. In this example, the video's width is 480 px
and height is 354 px
, so the CSS should look like the following:
With this CSS, the browser knows how much space to allocate for the video before it has even been started downloading. As a result, you've eliminated the layout shift.
Okay, now you have an optimized video that serves different formats based on browser support and doesn't cause a Cumulative Layout Shift after it loads. Let's examine the WebPageTest waterfall chart at this point.
This waterfall shows that the video's first frame only appears after the entire video finishes downloading. Ideally, that should render as quickly as possible to indicate visual progress. This also affects the LCP since it's the first frame of an autoplaying video.
Luckily, there's another trick you can use for this.
Step 5: Add a poster image
Using the
poster
attribute
with a small image, you can encourage the browser to paint the first
frame faster. That instructs the browser to download and display an
image while the video is loading.
Given that this image will only show initially, you should apply heavy compression to it so that it downloads as quickly as possible. Shoot for an image file size that's less than 5 KB. Remember, its only purpose is to indicate visual progress, so it's okay if the quality is low.
Using FFmpeg, you can use the following command to extract the first frame of the video as an image.
If the quality is too low, raise it by lowering the qscale:v
option
(1 is the highest quality, 31 is the lowest quality).
You can also use Cloudinary to get the first frame of the GIF by
replacing the .gif
file extension with .jpg
in the URL. To lower
the quality and reduce the image's file size, add q_5
to the path.
Next, add the image to the poster attribute:
Now WebPageTest shows the first frame rendering about 100ms earlier for most runs:
Step 6: Lazy-load videos below the fold
In this example, we're only replacing one animated GIF, and it's above the fold. But like offscreen images, try to lazy-load all videos below the fold for the best performance.
Step 7: Measure the impact
Let's test the page with the video and compare it to the page with the GIF.
Testing the video with PageSpeed Insights results in a perfect score. That's a 25-point improvement over the page with a GIF.
Comparing the GIF test results with the video test results from WebPageTest shows more improvements:
- 97% decrease in file size (2,392 KB GIF down to 69 KB video with 5 KB poster)
- 95% decrease in page weight (2,442 KB down to 122 KB)
- 100 ms improvement in LCP
- 65% decrease in page load time (3.616 seconds down to 1.247 seconds)
Conclusion
Replacing animated GIFs with optimized videos can improve your website's performance, including load time, LCP, and page weight.