![Rob Dodson](https://web.dev/images/authors/robdodson.jpg) Rob Dodson [X](https://twitter.com/rob_dodson) [GitHub](https://github.com/robdodson) [Homepage](https://robdodson.me)

<br />

> [!IMPORTANT]
> To follow this codelab, open [this Glitch](https://glitch.com/edit/#!/gif-to-video) in a second tab.

> [!NOTE]
> **Note:** This codelab uses Chrome DevTools. [Download Chrome](https://www.google.com/chrome) if you don't already have it.

In this codelab, improve performance by replacing an animated GIF with a
video.

## Measure first

First measure how the website performs:

1. To preview the site, press **View App** . Then press **Fullscreen** ![fullscreen](https://web.dev/static/images/glitch/fullscreen.svg).
2. Press \`Control+Shift+J\` (or \`Command+Option+J\` on Mac) to open DevTools.
3. Click the **Lighthouse** tab.
4. Make sure the **Performance** checkbox is selected in the *Categories* list.
5. Click the **Generate report** button.

When you're finished, you should see that Lighthouse has flagged the GIF as an
issue in its "Use video formats for animated content" audit.

## Get FFmpeg

There are a number of ways you can convert GIFs to video; this guide uses
**[FFmpeg](https://www.ffmpeg.org/)** . It's already installed in the Glitch VM,
and, if you want, you can follow [these instructions to install it on your
local
machine](https://web.dev/articles/replace-gifs-with-videos#create_mpeg_videos)
as well.

## Open the console

Double-check that FFmpeg is installed and working:

1. Click **Remix to Edit** to make the project editable.
2. Click **Terminal** (note: if the Terminal button does not show you may need to use the Fullscreen option).
3. In the console, run:

```bash
which ffmpeg
```

You should get a file path back:

```bash
/usr/bin/ffmpeg
```

## Change GIF to video

- In the console, run `cd images` to enter the images directory.
- Run `ls` to see the contents.

You should see something like this:

```bash
$ ls
cat-herd.gif
```

- In the console, run:

```bash
ffmpeg -i cat-herd.gif -b:v 0 -crf 25 -f mp4 -vcodec libx264 -pix_fmt yuv420p cat-herd.mp4
```

This tells FFmpeg to take the **input** , signified by the `-i` flag, of
cat-herd.gif and convert it to a video called cat-herd.mp4. This should take a
second to run. When the command finishes, you should be able to type `ls` again
and see two files:

```bash
$ ls
cat-herd.gif  cat-herd.mp4
```

## Create WebM videos

While MP4 has been around since 1999, WebM is a relative newcomer having been
initially released in 2010. WebM videos can be much smaller than MP4 videos, so
it makes sense to generate both. Thankfully the `<video>` element will let you
add multiple sources, so if a browser doesn't support WebM, it can fallback to
MP4.

- In the console, run:

```bash
ffmpeg -i cat-herd.gif -c vp9 -b:v 0 -crf 41 cat-herd.webm
```

- To check the file sizes run:

```bash
ls -lh
```

You should have one GIF, and two videos:

```bash
$ ls -lh
total 4.5M
-rw-r--r-- 1 app app 3.7M May 26 00:02 cat-herd.gif
-rw-r--r-- 1 app app 551K May 31 17:45 cat-herd.mp4
-rw-r--r-- 1 app app 341K May 31 17:44 cat-herd.webm
```

Notice that the original GIF is 3.7M, whereas the MP4 version is 551K, and the
WebM version is only 341K. That's a huge savings!

## Update HTML to recreate GIF effect

Animated GIFs have three key traits that videos need to replicate:

- They play automatically.
- They loop continuously (usually, but it is possible to prevent looping).
- They're silent.

Luckily, you can recreate these behaviors using the `<video>` element.

- In the `index.html` file, replace the line with the `<img>` with:

    <img src="/images/cat-herd.gif" alt="Cowboys herding cats.">
    <video autoplay loop muted playsinline></video>

A `<video>` element using these attributes will play automatically, loop
endlessly, play no audio, and play inline (that is, not fullscreen), all the
behaviors expected of animated GIFs! 🎉

## Specify your sources

All that's left to do is specify your video sources. The `<video>` element requires
one or more `<source>` child elements pointing to different video files the
browser can choose from, depending on format support.
Update the `<video>` with `<source>` elements that link to your cat-herd videos:

    <video autoplay loop muted playsinline>
      <source src="/images/cat-herd.webm" type="video/webm">
      <source src="/images/cat-herd.mp4" type="video/mp4">
    </video>

> [!NOTE]
> **Note:** Browsers don't speculate about which `<source>` is optimal, so the order of `<source>`s matters. For example, if you specify an MP4 video first and the browser supports WebM, browsers will skip the WebM `<source>` and use the MPEG-4 instead. If you prefer a WebM `<source>` be used first, specify it first!

## Preview

- To preview the site, press **View App** . Then press **Fullscreen** ![fullscreen](https://web.dev/static/images/glitch/fullscreen.svg).

The experience should look the same. So far so good.

## Verify with Lighthouse

With the live site open:

1. Press \`Control+Shift+J\` (or \`Command+Option+J\` on Mac) to open DevTools.
2. Click the **Lighthouse** tab.
3. Make sure the **Performance** checkbox is selected in the *Categories* list.
4. Click the **Generate report** button.

You should see that the "Use video formats for animated content" audit is now
passing! Woohoo! 💪