Como Substituir GIFs Animados por Vídeo MP4
Substitua GIFs animados por vídeo MP4 ou WebM com autoplay muted loop playsinline, além de conversão ffmpeg e dicas de LCP.
Para substituir um GIF animado por vídeo, converta o clipe para um MP4 em H.264 e um WebM em VP9, e então incorpore ambos com <video autoplay muted loop playsinline>, listando o <source> do WebM primeiro.
Se o Lighthouse sinalizou a página do seu produto ou sua documentação por conteúdo animado, a causa normalmente é um GIF de gravação de tela pesando vários megabytes. Este artigo mostra por que o GIF perde em tamanho, a conversão (ferramenta de navegador ou ffmpeg, você escolhe), a marcação exata, o que a troca faz com o LCP, e onde o GIF ainda é a escolha certa.
Pontos Principais
- Um GIF animado armazena cada frame como uma imagem quase completa com no máximo 256 cores, portanto não obtém nenhuma da compressão interframe sobre a qual os codecs de vídeo são construídos.
mutedé o que faz os navegadores permitirem o autoplay em primeiro lugar, eplaysinlineé o que impede o iOS de forçar o vídeo para tela cheia.- Os navegadores reproduzem o primeiro
<source>que conseguem decodificar, não o menor, então a source WebM deve vir antes do fallback MP4. - Desde o Chrome 116, um
<video>semposterpode contar como o elemento LCP, e o tempo registrado é o momento em que seu frame de abertura chega à tela. - A economia de tamanho depende inteiramente do clipe; meça o seu antes e depois em vez de confiar em uma porcentagem citada.
Por Que o GIF é o Container Errado para Movimento?
Um GIF animado armazena cada frame como uma imagem quase completa com uma paleta de no máximo 256 cores por frame, portanto não obtém nenhuma da compressão interframe em torno da qual os formatos de vídeo foram projetados, e é decodificado em software, enquanto H.264 e VP9 têm caminhos de decodificação por hardware na maioria dos dispositivos. A especificação GIF89a diz claramente que o formato não foi feito para carregar animação e a permite apenas de forma limitada; o loop veio depois, adicionado pelos navegadores. Essa é toda a lição de história de que você precisa.
A consequência prática é que alguns segundos de gravação de tela rotineiramente ficam na faixa de vários megabytes como GIF e nas centenas de kilobytes como vídeo. O Lighthouse expõe isso: o conselho de GIF-para-vídeo agora fica dentro do insight Improve image delivery a partir do Lighthouse 13.
Uma Conversão Real, Com Números Reais
O guia da web.dev sobre este tópico do Google publica um exemplo honesto, convertido com os mesmos comandos mostrados abaixo: um GIF de origem de 3,7 MB tornou-se um MP4 de 551 KB e um WebM de 341 KB. A economia depende inteiramente do conteúdo do clipe, da taxa de frames e das dimensões, portanto uma porcentagem medida em um arquivo não se generaliza para o seu.
| Arquivo | Tamanho |
|---|---|
| GIF de origem | 3,7 MB |
| MP4 (H.264, CRF 25) | 551 KB |
| WebM (VP9, CRF 41) | 341 KB |
Trate esses números como um único ponto de dados, não como uma regra. Filmagens com muito movimento comprimem de forma diferente de uma gravação de terminal quase estática. Passe seu próprio clipe pelos passos abaixo e compare a contagem de bytes antes de se comprometer.
Como Substituir um GIF por Vídeo: Criando os Arquivos
Você precisa de dois arquivos: um MP4 para reprodução universal e um WebM que normalmente é menor. Cada passo tem uma ferramenta de navegador e um comando ffmpeg equivalente.
Passo 1: GIF para MP4. Use o conversor GIF to MP4, que roda localmente no seu navegador, ou o ffmpeg:
ffmpeg -i input.gif -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" \
-vcodec libx264 -pix_fmt yuv420p -b:v 0 -crf 25 -f mp4 output.mp4
-pix_fmt yuv420p mantém o arquivo reproduzível em qualquer lugar, e o CRF vai de 0 a 51, sendo menor igual a maior qualidade, com -b:v 0 desativando o limite de bitrate no modo CRF. O filtro de crop é a solução alternativa da web.dev para o libx264 rejeitar dimensões de pixel ímpares.
Passo 2: o arquivo WebM, para o segundo <source>. No navegador, alimente o MP4 que você acabou de criar no conversor MP4 to WebM. Com o ffmpeg, codifique direto a partir do GIF original em vez disso, para que o clipe não seja comprimido duas vezes:
ffmpeg -i input.gif -c:v libvpx-vp9 -b:v 0 -crf 41 output.webm
A escala CRF do VP9 difere daquela do x264, e é por isso que 41 aqui é um padrão sensato em vez de uma configuração de baixa qualidade.
Passo 3: Ajuste opcional. Se o resultado ainda estiver pesado, reduza-o por resolução e qualidade com o compressor de vídeo, ou com o ffmpeg:
ffmpeg -i output.mp4 -vf scale=640:-2 -crf 28 -movflags faststart smaller.mp4
-movflags faststart move os metadados do MP4 para o início do arquivo, para que a reprodução possa começar antes de o download terminar.
A Marcação Que Se Comporta Como um GIF
Para fazer um vídeo se comportar como um GIF, use <video autoplay muted loop playsinline>: muted é o que faz os navegadores permitirem o autoplay em primeiro lugar, e playsinline é o que impede o iOS de forçar o vídeo para tela cheia.
<video autoplay muted loop playsinline width="640" height="360">
<source src="clip.webm" type="video/webm">
<source src="clip.mp4" type="video/mp4">
</video>
A política de autoplay do Chrome permite que um vídeo silenciado comece por conta própria, e retém o autoplay com som até que o visitante tenha interagido com o site. A política de vídeo do WebKit para iOS permite que vídeos façam autoplay sem um gesto apenas quando estão silenciados ou não carregam faixa de áudio, e o iPhone precisa de playsinline para reproduzir o clipe no lugar. A ordem das sources importa porque os navegadores não escolhem o melhor <source>; eles reproduzem o primeiro que conseguem decodificar, então o WebM menor vem primeiro. Essa ordem é segura em todos os lugares: a tabela do WebM no caniuse mostra suporte completo no Safari 16 no macOS e no Safari no iOS a partir do 17.4, portanto os avisos da era de 2018 sobre Apple e WebM não se aplicam mais. Os atributos width e height reservam espaço de layout, a mesma cortesia de CLS que você daria a uma imagem.
Quando um desses atributos está ausente, a falha é silenciosa: nenhum erro no console, nenhum ícone de imagem quebrada, apenas um primeiro frame congelado. O session replay mostra a página como cada usuário realmente a viu, o que é a única forma confiável de detectar um vídeo com autoplay que nunca começou em produção.
O Que a Troca Faz com o Largest Contentful Paint?
Trocar <img> por <video> muda qual elemento pode ser seu candidato a LCP. Orientações mais antigas diziam que um <video> sem poster é invisível para o LCP, mas isso mudou no Chrome 116: o changelog de métricas do Chromium registra que um elemento de vídeo agora é elegível da mesma forma que uma imagem, com seu timestamp tomado a partir do momento em que o frame de abertura chega à tela. Portanto, não adicione um poster apenas para burlar a métrica; um vídeo com autoplay pinta seu primeiro frame imediatamente, e a imagem de poster nunca seria vista. Se sua animação de destaque for o maior elemento, seu tempo de LCP agora depende de quão rápido esse primeiro frame chega, mais um motivo para manter os arquivos pequenos.
Quando um GIF Ainda Vence?
Um GIF ainda vence onde você não pode controlar a marcação: mensagens de chat, clientes de e-mail e READMEs do GitHub renderizam um GIF inline, mas não incorporam um vídeo com autoplay. Nesses ambientes, a portabilidade vence o peso da página, e a atitude correta é a compressão lossy de GIF em vez da conversão. A opção --lossy do gifsicle (antes o projeto separado giflossy) troca artefatos por tamanho:
gifsicle -O3 --lossy=80 -o smaller.gif input.gif
Valores mais altos de lossiness permitem mais artefatos e arquivos menores; ajuste até a saída deixar de parecer aceitável, e então recue.
Concluindo
Em qualquer página cuja marcação você controla, o movimento pertence a um elemento <video> com duas sources, não a um GIF. Escolha o GIF mais pesado do seu site, passe-o pelos passos de conversão acima e compare a contagem de bytes você mesmo; então publique a marcação de quatro atributos com o WebM primeiro e verifique o replay de uma sessão real para confirmar que ele realmente reproduz.
Perguntas Frequentes
Posso servir apenas um MP4 e dispensar o arquivo WebM?
Sim. Um MP4 em H.264 no formato de pixel yuv420p reproduz em todos os navegadores modernos, portanto um elemento de vídeo com uma única source funciona em qualquer lugar e nada quebra. A versão WebM é uma otimização de tamanho, não um requisito de compatibilidade: o VP9 normalmente produz um arquivo menor com qualidade similar. Publique o MP4 primeiro e depois adicione a source WebM acima dele, mais tarde, se o peso da página ainda te incomodar.
Por que meu vídeo ainda não faz autoplay mesmo com autoplay, muted, loop e playsinline definidos?
Uma política do user agent está bloqueando a reprodução, não sua marcação. O Safari no iOS suspende o autoplay quando o dispositivo está em Modo de Baixo Consumo e sobrepõe um botão de play em vez disso, e modos de economia de bateria ou de dados em outros navegadores podem se comportar de forma semelhante. Detecte isso em JavaScript: video.play() retorna uma promise, então trate a rejeição exibindo controles ou uma imagem estática de fallback em vez de um frame congelado.
loading='lazy' funciona no elemento de vídeo?
Em navegadores baseados em Chromium, sim. Chrome, Edge e Opera adiam o download de um vídeo lazy, a busca do poster e o autoplay até que o elemento se aproxime da viewport, e o MDN documenta o atributo. Uma adição correspondente à especificação HTML está em andamento, e Firefox e WebKit ambos deram à funcionalidade uma posição positiva quanto aos padrões, mas nenhum dos dois a lançou ainda. Navegadores sem suporte simplesmente ignoram o atributo e carregam de forma eager, portanto adicioná-lo a vídeos fora da tela que substituem GIFs é seguro hoje.
O WebP animado é um bom meio-termo entre GIF e vídeo?
Às vezes. O WebP animado funciona dentro de um elemento img simples, suporta cor de 24 bits em vez da paleta de 256 cores do GIF, e normalmente produz arquivos menores que o GIF equivalente. Mas ele não se equipara a um codec de vídeo real: H.264 ou VP9 comprime uma gravação de tela muito melhor. Use WebP animado onde o ambiente exige uma tag de imagem mas aceita formatos modernos, e use vídeo onde você controla a marcação.