Cómo reemplazar GIFs animados por vídeo MP4
Reemplaza GIF animados por video MP4 o WebM con autoplay muted loop playsinline, además de conversión con ffmpeg y consejos de LCP.
Para reemplazar un GIF animado por vídeo, convierte el clip a un MP4 H.264 y a un WebM VP9, y luego incrusta ambos con <video autoplay muted loop playsinline>, colocando el <source> WebM en primer lugar.
Si Lighthouse ha marcado la página de tu producto o tu documentación por contenido animado, la causa suele ser un GIF de grabación de pantalla que pesa varios megabytes. Este artículo explica por qué el GIF pierde en cuanto a tamaño, cómo hacer la conversión (herramienta de navegador o ffmpeg, tú eliges), el marcado exacto, qué efecto tiene el cambio sobre el LCP y en qué casos el GIF sigue siendo la opción correcta.
Puntos clave
- Un GIF animado almacena cada fotograma como una imagen prácticamente completa con un máximo de 256 colores, por lo que no aprovecha nada de la compresión entre fotogramas sobre la que se construyen los códecs de vídeo.
mutedes lo que hace que los navegadores permitan la reproducción automática, yplaysinlinees lo que impide que iOS fuerce el vídeo a pantalla completa.- Los navegadores reproducen el primer
<source>que pueden decodificar, no el más pequeño, así que la fuente WebM debe ir antes del fallback en MP4. - Desde Chrome 116, un
<video>sinposterpuede contar como elemento LCP, y el tiempo registrado es el momento en que su primer fotograma llega a la pantalla. - El ahorro de tamaño depende por completo del clip; mide tu propio caso antes y después en lugar de fiarte de un porcentaje citado.
¿Por qué GIF es el contenedor equivocado para el movimiento?
Un GIF animado almacena cada fotograma como una imagen prácticamente completa con una paleta de como máximo 256 colores por fotograma, por lo que no aprovecha nada de la compresión entre fotogramas para la que fueron diseñados los formatos de vídeo, y se decodifica por software mientras que H.264 y VP9 disponen de rutas de decodificación por hardware en la mayoría de dispositivos. La especificación GIF89a dice claramente que el formato no estaba pensado para transportar animación y solo la permite de forma limitada; el bucle llegó después, añadido por los navegadores. Esa es toda la lección de historia que necesitas.
La consecuencia práctica es que unos pocos segundos de grabación de pantalla suelen situarse en el rango de varios megabytes como GIF y en los cientos de kilobytes como vídeo. Lighthouse lo señala: el consejo de pasar de GIF a vídeo ahora reside dentro de la insight «Improve image delivery» a partir de Lighthouse 13.
Una conversión real, con números reales
La guía de web.dev sobre este tema de Google publica un ejemplo honesto, convertido con los mismos comandos que se muestran abajo: un GIF de origen de 3,7 MB pasó a ser un MP4 de 551 KB y un WebM de 341 KB. El ahorro depende por completo del contenido del clip, la tasa de fotogramas y las dimensiones, así que un porcentaje medido en un archivo no se generaliza al tuyo.
| Archivo | Tamaño |
|---|---|
| GIF de origen | 3,7 MB |
| MP4 (H.264, CRF 25) | 551 KB |
| WebM (VP9, CRF 41) | 341 KB |
Trata esas cifras como un dato puntual, no como una regla. El material con mucho movimiento se comprime de forma distinta a una grabación de terminal mayormente estática. Pasa tu propio clip por los pasos siguientes y compara los bytes antes de decidirte.
Cómo reemplazar un GIF por vídeo: crear los archivos
Necesitas dos archivos: un MP4 para reproducción universal y un WebM que normalmente será más pequeño. Cada paso incluye una herramienta de navegador y un comando de ffmpeg equivalente.
Paso 1: de GIF a MP4. Usa el conversor de GIF a MP4, que se ejecuta localmente en tu navegador, 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 mantiene el archivo reproducible en todas partes, y el CRF va de 0 a 51, donde un valor más bajo significa mayor calidad, con -b:v 0 desactivando el límite de bitrate en modo CRF. El filtro de recorte es la solución alternativa de web.dev para que libx264 no rechace dimensiones de píxel impares.
Paso 2: el archivo WebM, para el segundo <source>. En el navegador, pasa el MP4 que acabas de crear por el conversor de MP4 a WebM. Con ffmpeg, codifica directamente desde el GIF original, de modo que el clip no se comprima dos veces:
ffmpeg -i input.gif -c:v libvpx-vp9 -b:v 0 -crf 41 output.webm
La escala CRF de VP9 difiere de la de x264, y por eso 41 aquí es un valor por defecto razonable y no un ajuste de baja calidad.
Paso 3: ajuste opcional. Si el resultado sigue siendo pesado, redúcelo en resolución y calidad con el compresor de vídeo, o con ffmpeg:
ffmpeg -i output.mp4 -vf scale=640:-2 -crf 28 -movflags faststart smaller.mp4
-movflags faststart mueve los metadatos del MP4 al principio del archivo para que la reproducción pueda comenzar antes de que termine la descarga.
El marcado que se comporta como un GIF
Para que un vídeo se comporte como un GIF, usa <video autoplay muted loop playsinline>: muted es lo que hace que los navegadores permitan la reproducción automática, y playsinline es lo que impide que iOS fuerce el vídeo a pantalla completa.
<video autoplay muted loop playsinline width="640" height="360">
<source src="clip.webm" type="video/webm">
<source src="clip.mp4" type="video/mp4">
</video>
La política de autoplay de Chrome permite que un vídeo silenciado se inicie por sí solo, y retiene la reproducción automática con sonido hasta que el visitante ha interactuado con el sitio. La política de vídeo de WebKit para iOS permite que los vídeos se reproduzcan automáticamente sin un gesto solo cuando están silenciados o no tienen pista de audio, y el iPhone necesita playsinline para reproducir el clip en su sitio. El orden de las fuentes importa porque los navegadores no eligen el mejor <source>; reproducen el primero que pueden decodificar, así que el WebM más pequeño va primero. Ese orden es seguro en todas partes: la tabla de WebM en caniuse muestra soporte completo en Safari 16 en macOS y en Safari en iOS desde 17.4, por lo que las advertencias de 2018 sobre Apple y WebM ya no aplican. Los atributos width y height reservan espacio de layout, la misma cortesía frente al CLS que le darías a una imagen.
Cuando falta alguno de estos atributos, el fallo es silencioso: sin error en consola, sin icono de imagen rota, solo un primer fotograma congelado. El session replay muestra la página tal como cada usuario la vio realmente, que es la única forma fiable de detectar un vídeo con autoplay que nunca arrancó en producción.
¿Qué efecto tiene el cambio sobre el Largest Contentful Paint?
Cambiar <img> por <video> modifica qué elemento puede ser tu candidato a LCP. Las recomendaciones más antiguas decían que un <video> sin poster es invisible para el LCP, pero eso cambió en Chrome 116: el changelog de métricas de Chromium registra que un elemento de vídeo ahora es elegible del mismo modo que una imagen, con su marca de tiempo tomada en el momento en que el primer fotograma llega a la pantalla. Así que no añadas un poster solo para manipular la métrica; un vídeo con autoplay pinta su primer fotograma de inmediato, y la imagen del poster nunca se vería. Si tu animación principal es el elemento más grande, su tiempo de LCP depende ahora de la rapidez con la que llegue ese primer fotograma, una razón más para mantener los archivos pequeños.
¿Cuándo sigue ganando un GIF?
Un GIF sigue ganando allí donde no controlas el marcado: mensajes de chat, clientes de correo y READMEs de GitHub renderizan un GIF en línea, pero no incrustarán un vídeo con reproducción automática. En esos entornos, la portabilidad vence al peso de página, y lo correcto es aplicar compresión GIF con pérdida en lugar de conversión. La opción --lossy de gifsicle (antes el proyecto independiente giflossy) intercambia artefactos por tamaño:
gifsicle -O3 --lossy=80 -o smaller.gif input.gif
Valores de pérdida más altos permiten más artefactos y archivos más pequeños; ajusta hasta que la salida deje de verse aceptable, y luego retrocede.
Conclusión
En cualquier página cuyo marcado controles, el movimiento pertenece a un elemento <video> con dos fuentes, no a un GIF. Elige el GIF más pesado de tu sitio, pásalo por los pasos de conversión anteriores y compara tú mismo los bytes; luego publica el marcado con los cuatro atributos y el WebM primero, y revisa la reproducción de una sesión real para confirmar que efectivamente se reproduce.
Preguntas frecuentes
¿Puedo servir solo un MP4 y prescindir del archivo WebM?
Sí. Un MP4 H.264 en formato de píxel yuv420p se reproduce en todos los navegadores modernos, así que un elemento de vídeo con una sola fuente funciona en todas partes y no se rompe nada. La versión WebM es una optimización de tamaño, no un requisito de compatibilidad: VP9 suele producir un archivo más pequeño con una calidad similar. Publica primero el MP4 y, si el peso de la página te sigue preocupando, añade después la fuente WebM por encima.
¿Por qué mi vídeo sigue sin reproducirse automáticamente aunque tenga autoplay, muted, loop y playsinline?
Es una política del agente de usuario la que está bloqueando la reproducción, no tu marcado. Safari en iOS suspende la reproducción automática cuando el dispositivo está en Modo de bajo consumo y superpone un botón de reproducción en su lugar, y los modos de ahorro de batería o de datos en otros navegadores pueden comportarse de forma similar. Detéctalo en JavaScript: video.play() devuelve una promesa, así que gestiona el rechazo mostrando controles o una imagen estática de respaldo en vez de un fotograma congelado.
¿Funciona loading='lazy' en el elemento de vídeo?
En los navegadores basados en Chromium, sí. Chrome, Edge y Opera aplazan la descarga de un vídeo lazy, la obtención del poster y la reproducción automática hasta que el elemento se acerca al viewport, y MDN documenta el atributo. Una incorporación equivalente a la especificación HTML está en curso, y tanto Firefox como WebKit han dado a la función una posición favorable respecto a los estándares, pero ninguno la ha implementado todavía. Los navegadores sin soporte simplemente ignoran el atributo y cargan de forma inmediata, así que añadirlo hoy a vídeos de reemplazo de GIF que están fuera de pantalla es seguro.
¿Es el WebP animado un buen punto intermedio entre GIF y vídeo?
A veces. El WebP animado funciona dentro de un elemento img normal, admite color de 24 bits en lugar de la paleta de 256 colores del GIF y suele producir archivos más pequeños que el GIF equivalente. Pero no está a la altura de un códec de vídeo real: H.264 o VP9 comprimen una grabación de pantalla mucho mejor. Usa WebP animado cuando el entorno exija una etiqueta de imagen pero acepte formatos modernos, y usa vídeo siempre que controles el marcado.