Have you ever seen an animated GIF on a service like Imgur or Gfycat and inspected it in DevTools, only to find out that GIF was really a video? There's a good reason for that. Animated GIFs can be downright huge. It's not uncommon for GIFs to tip the scales at several megabytes, depending on quality, frame rate, and length. If you're trying to improve loading performance for your site and help users reduce data usage, animated GIF just isn't compatible with that goal.
Thankfully, this is one of those areas of loading performance where you can do relatively little work to realize huge gains without sacrificing content quality. In this article, you're going to learn how to do what the GIF hosting sites do to keep their bandwidth bills from going through the roof, and convert those giant GIFs into lean and fast video files! You'll then learn how to properly embed these videos in web pages so they behave just like GIFs. Finally, we'll talk a little bit about decoding performance for both GIF and video. Before you know it, you'll be well on your way to shaving megabytes off your GIF-heavy web pages in no time at all!
Converting animated GIFs to video
There are a number of ways you can convert GIFs to video, but
ffmpeg is the tool we'll use in this guide. You may
ffmpeg installed. To check, open a terminal and run the
command. If it's installed, you'll see some diagnostic information. If you
receive a "command not found" or similar error, you'll need to install it. How
ffmpeg depends on the
- For macOS, you can install via Homebrew or compile it yourself.
- For Windows, use Chocolatey.
- For Linux, check if your preferred distro's package manager (e.g., apt-get or yum) has a package available.
ffmpeg is installed, pick a GIF, and you'll be ready to roll. For the
purposes of this guide, I picked this
GIF, which is just shy of 14 MB. To
start off, let's try our hand at converting a GIF to MPEG-4!
Converting GIF to MPEG-4
Whenever you embed videos on a page, you'll always want to have an MPEG-4 version as MPEG-4 enjoys the broadest support of all video formats across browsers. To get started, open a terminal window, go to the directory containing your test GIF, and try this command:
ffmpeg -i input.gif output.mp4
This is the most straightforward syntax for converting a GIF to MPEG-4. The
flag specifies the input, and we specify an output file thereafter. This command
takes our test GIF of 14,024 KB and reduces it to a reasonably high quality
MPEG-4 video weighing in 867 KB. That's a reduction of 93.8%. Not bad,
but maybe you're curious to see if we can go a little further. If so, keep
It turns out ffmpeg is super configurable, and we can use this to our advantage to fine-tune the video output further by employing an encoding mode called Constant Rate Factor (or CRF). CRF is great when video quality is a high priority.
ffmpeg -i input.gif -b:v 0 -crf 25 output.mp4
This command is largely similar to the one before it, but with two key
-b:v flag normally would limit the output
when we want to use CRF mode, it must be set to
-crf flag accepts a
51. Lower values yield higher quality (but larger)
videos, whereas higher values do the opposite.
Using our test GIF, this command outputs an MPEG-4 video 687 KB in size. That's an improvement of roughly 20%! If you want even smaller file sizes, you could specify a higher CRF value. Just be aware that higher values will yield lower quality videos, so always check the encoder's output to ensure you're cool with the results!
In any event, both these commands yield a massive reduction in file size over GIF, which in turn will substantially improve initial page load time and reduce data usage. While the visual quality of the video is somewhat lower than source GIF, the reduction in file size is a reasonable trade-off to make:
While the figure above is no substitute for a comprehensive visual comparison, the MPEG-4 is certainly sufficient as an animated GIF replacement. It also pays to remember that your users likely won't have a reference to the GIF source like you will. Always adhere to your project's standards for media quality, but be willing to make trade-offs for performance where appropriate.
If the resulting .mp4 won't open in Quicktime, Safari will not load it. Instead, try the command below to generate an mp4 that should load in Safari:
ffmpeg -i input.gif -b:v 0 -crf 25 -f mp4 -vcodec libx264 -pix_fmt yuv420p output.mp4
This additional config
-f mp4 -vcodec libx264 -pix_fmt yuv420p should set the
correct codec for Quicktime player so Safari browser will recognize the .mp4 file.
While MPEG-4 is broadly compatible and certainly suitable as an animated GIF replacement, we can go just a bit further by generating an additional WebM source. Read on to learn more!
Converting GIF to WebM
While MPEG-4 has been in around in some form since at least
1999 and continues to see
development, WebM is a relative newcomer having been initially released in
2010. While browser
support for WebM isn't as wide as MPEG-4, it's
still very good. Because the
you to specify multiple
you can state a preference for a WebM source that many browsers can use while
falling back to an MPEG-4 source that all other browsers can understand.
Try converting your test GIF to WebM with
ffmpeg with this command:
ffmpeg -i input.gif -c vp9 -b:v 0 -crf 41 output.webm
You'll notice this method is mostly similar to the previous GIF to MPEG-4 conversion command using CRF mode, but there are two key differences:
- The codec we specify in the
vp9, which is the successor to the VP8 codec used by the WebM format. If this fails for you, replace
- Because CRF values don't yield equivalent results across formats, we need to
adjust it so our WebM output is visually similar to the MPEG-4 output. A
41is used in this example to achieve reasonably comparable quality to the MPEG-4 version while still outputting a smaller file.
In this example, the WebM version was roughly 66 KB smaller than the MPEG-4 at 611 KB. Its visual quality is reasonably similar to the MPEG-4 version, too.
Due to how the VP8 and VP9 codecs encode video, compression artifacts in WebM may affect the quality of the result in ways different than in MPEG-4. As always, inspect the encoder output and experiment with flags (time permitting) to find the best result for your application.
Now that we know how to convert GIFs to both MPEG-4 and WebM, let's learn how to
replace those animated GIF
<img> elements with
Replacing animated GIF
<img> elements with
Unfortunately, using a video as an animated GIF replacement is not quite as
straightforward as dropping an image URL into an
<img> element. Using
<video> is a bit more complex, but not onerously so. We'll walk through how to
do this step by step and explain everything, but if you just want to see the
code, check out this CodePen demo.
Getting the behaviors right
Animated GIFs have three key traits:
- They play automatically.
- They loop continuously (usually, but it is possible to prevent looping).
- They're silent.
The only true advantage of using animated GIF over video is convenience. We
don't have to be explicit in defining these traits when we embed GIFs. They just
behave the way we expect them to. When we want to use video in place of GIFs,
however, we have to explicitly tell the
<video> element to autoplay, loop
continuously, and be silent. Let's start by writing a
<video> element like so:
<video autoplay loop muted playsinline></video>
The attributes in this example are pretty self-explanatory. A
using these attributes will play automatically, loop endlessly, play no audio,
and play inline (i.e., not fullscreen). In other words, all the hallmark
behaviors we expect of animated GIFs.
There's more to this than simply emulating GIF behavior, though. Some of these
attributes are required for autoplay to even work. For example, the
attribute must be present for videos to
autoplay, even if they don't contain an audio track. On iOS, the
attribute is required for autoplay to
work as well.
All that's left to do is specify your video sources. The
requires one or more
<source> child elements pointing to different video files
the browser can choose from, depending on format support:
<video autoplay loop muted playsinline> <source src="oneDoesNotSimply.webm" type="video/webm"> <source src="oneDoesNotSimply.mp4" type="video/mp4"> </video>
Now that we know how to convert GIFs to video and how to use those videos as GIF replacements, let's see how each of these solutions performs in the browser.
Performance of video versus animated GIF
Though smaller resources are preferable, file size isn't everything. We also need to be cognizant of how a media resource performs after it has been downloaded, because media assets must be decoded before playback.
GIFs (and other animated image formats) are suboptimal because an image decode
is incurred for every frame in the image, which can contribute to jank. This
makes sense, because each frame in a GIF is simply another image. Let's see how
this looks in the Performance panel in Chrome's developer tools for a page where
the only content is an
<img> element pointing to an animated GIF:
As you can see in the above figure, image decodes occurs on the rasterizer threads as each new frame of the GIF is decoded. Now let's look at a comparison table of total CPU time for GIF versus MPEG-4 and WebM videos:
These figures were gathered in Chrome's tracing utility (record your own Chrome
chrome://tracing) over a period of ~6.5 seconds for each format. As
you can see, GIF takes the most CPU time, and less CPU time occurs for both
videos, particularly MPEG-4. This is good stuff! It means that videos generally
use less CPU time than animated GIF, which is a welcome performance enhancement
beyond simply reducing file size.
It should be mentioned, however, that some CPUs and GPUs offer hardware-accelerated encoding/decoding of video (e.g., Quick Sync Video on Intel CPUs). Many processors can handle encoding and decoding for MPEG-4, but WebM codecs such as VP8 and VP9 have only recently started to benefit from hardware-accelerated encoding/decoding on newer CPUs. A Kaby Lake Intel processor was used in these tests, meaning that video decoding was hardware assisted.
You've heard enough about the advantages of using video instead of animated GIF, but I would be remiss in my responsibility if I didn't also point out some of the potential pitfalls. Here's a couple for your consideration.
Embedding video is not as convenient as embedding a GIF
Nothing is more convenient than slapping a GIF in an
<img> element and moving
on with your life. It's a simple one liner that just works, and that's huge for
the developer experience.
However, your experience as a developer isn't the only one that matters. Users
matter, too. On the bright side, using video in the
possible in Safari, so an easier solution for using videos as GIF replacements
may be on the way. It's just not an approach you can currently depend on in
Encoding your own videos can take time
As developers, we want to save time. When it comes to something as subjective as the notion of media quality, however, it can be difficult to come up with an automated process that provides the best results for all scenarios.
The safest thing to do is to analyze the encoder output for each video, and ensure the results are up to snuff. This may only be a reasonable solution for projects with few video resources. For larger projects with many videos, however, you may want to go with a conservative encoding strategy that emphasizes quality over file size. The good news is that this strategy will still yield great results, substantially improve loading performance, and reduce data usage for all users over relying on animated GIFs.
Additionally, converting all your GIFs to video takes time. Time you might not have. In this case, you might consider a cloud-based media hosting service such as Cloudinary or Uploadcare, which does the work for you. Check out this resource from Cloudinary's blog, which explains how their service can transcode GIF to video for you.
Data saver mode
On Chrome for Android, autoplaying video can be disallowed when Data Saver is enabled, even if you follow this guide's instructions to the letter. If you're a web developer, and you're struggling to figure out why videos aren't autoplaying on your Android device, disable Data Saver to see if that fixes the issue for you.
To cover edge cases such as these, you should consider setting the
attribute so the
<video> element's space is populated with some meaningful
content in the event Data Saver is on (or really any possible scenario where
autoplay could be disallowed). Another possible approach could be to set the
controls attribute conditionally based on the presence of the
which is a header Data Saver sends when it's active.
When you use video in lieu of animated GIF, you're doing your users a big favor by reducing the amount of data you send to them, as well as potentially reducing system resource usage. Ditching animated GIFs is worth serious consideration, especially if they feature prominently in your content. In a time where performance is more important than ever, yet many performance improvement strategies require a significant investment of time, transitioning your GIFs to video is a proportionally small effort when compared to the massive improvement it can have on loading performance.
We aren't the first to advocate for using videos instead of GIFs, and we won't be the last. For case studies or other perspectives on this topic, check out the following articles:
- Imgur Revamps GIFs for Faster Speeds and Higher Quality with GIFV
- Introducing GIFV
- GIF Revolution
- Those GIFs on Twitter Aren't Actually GIFs