12k
All articles

Как заменить анимированные GIF на видео MP4

Замените анимированные GIF на MP4 или WebM с autoplay muted loop playsinline, а также конвертацией ffmpeg и советами по LCP.

OpenReplay Team
OpenReplay Team
Как заменить анимированные GIF на видео MP4

Чтобы заменить анимированный GIF видео, сконвертируйте ролик в MP4 (H.264) и WebM (VP9), а затем встройте оба файла через <video autoplay muted loop playsinline>, указав <source> с WebM первым.

Если Lighthouse отметил вашу страницу продукта или документацию из-за анимированного контента, причина обычно кроется в GIF-записи экрана весом в несколько мегабайт. В этой статье разбирается, почему GIF проигрывает по размеру, как выполнить конвертацию (браузерным инструментом или через ffmpeg — на ваш выбор), какая именно нужна разметка, что даёт такая замена для LCP и в каких случаях GIF всё ещё остаётся правильным выбором.

Ключевые выводы

  • Анимированный GIF хранит каждый кадр как почти полноценное изображение с палитрой максимум в 256 цветов, поэтому он не получает никакой межкадровой компрессии, на которой построены видеокодеки.
  • Именно muted позволяет браузерам вообще разрешить автовоспроизведение, а playsinline не даёт iOS принудительно открывать видео в полноэкранном режиме.
  • Браузеры воспроизводят первый <source>, который могут декодировать, а не самый компактный, поэтому источник WebM должен идти раньше запасного MP4.
  • Начиная с Chrome 116, <video> без атрибута poster может считаться LCP-элементом, и фиксируется момент, когда его первый кадр появляется на экране.
  • Экономия размера полностью зависит от конкретного ролика; измеряйте свои файлы до и после, а не полагайтесь на процентные цифры из статей.

Почему GIF — неподходящий контейнер для движения?

Анимированный GIF хранит каждый кадр как практически полноценное изображение с палитрой не более 256 цветов на кадр, поэтому он лишён межкадровой компрессии, вокруг которой строились видеоформаты, и декодируется программно, тогда как у H.264 и VP9 на большинстве устройств есть аппаратные пути декодирования. Спецификация GIF89a прямо говорит, что формат не предназначался для анимации и допускает её лишь в ограниченном виде; зацикливание появилось позже и было добавлено браузерами. Это весь необходимый вам исторический экскурс.

Практическое следствие: несколько секунд записи экрана в формате GIF регулярно занимают несколько мегабайт, а в виде видео — сотни килобайт. Lighthouse обращает на это внимание: начиная с Lighthouse 13, рекомендация о замене GIF на видео входит в Improve image delivery insight.

Одна реальная конвертация с реальными цифрами

В руководстве web.dev по этой теме от Google приведён один честный пример, сконвертированный теми же командами, что показаны ниже: исходный GIF весом 3,7 МБ превратился в MP4 на 551 КБ и WebM на 341 КБ. Экономия полностью зависит от содержимого ролика, частоты кадров и размеров, поэтому процент, измеренный на одном файле, не переносится на ваш.

ФайлРазмер
Исходный GIF3,7 МБ
MP4 (H.264, CRF 25)551 КБ
WebM (VP9, CRF 41)341 КБ

Воспринимайте эти числа как одну точку данных, а не как правило. Динамичное видео сжимается иначе, чем преимущественно статичная запись терминала. Прогоните собственный ролик по шагам ниже и сравните размеры в байтах, прежде чем принимать решение.

Как заменить GIF на видео: готовим файлы

Вам нужны два файла: MP4 для универсального воспроизведения и WebM, который обычно меньше. Для каждого шага есть браузерный инструмент и эквивалентная команда ffmpeg.

Шаг 1: GIF в MP4. Используйте конвертер GIF в MP4, который работает локально в браузере, или 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 обеспечивает воспроизводимость файла везде, а CRF принимает значения от 0 до 51, где меньше значит выше качество, причём -b:v 0 отключает ограничение битрейта в режиме CRF. Фильтр crop — это обходной приём от web.dev для случаев, когда libx264 отказывается работать с нечётными размерами в пикселях.

Шаг 2: файл WebM для второго <source>. В браузере передайте только что созданный MP4 в конвертер MP4 в WebM. При работе с ffmpeg кодируйте сразу из исходного GIF, чтобы ролик не сжимался дважды:

ffmpeg -i input.gif -c:v libvpx-vp9 -b:v 0 -crf 41 output.webm

Шкала CRF у VP9 отличается от шкалы x264 — именно поэтому 41 здесь является разумным значением по умолчанию, а не настройкой низкого качества.

Шаг 3: опциональная донастройка. Если результат всё ещё тяжёлый, уменьшите его по разрешению и качеству с помощью видеокомпрессора или через ffmpeg:

ffmpeg -i output.mp4 -vf scale=640:-2 -crf 28 -movflags faststart smaller.mp4

-movflags faststart перемещает метаданные MP4 в начало файла, чтобы воспроизведение могло начаться ещё до окончания загрузки.

Разметка, которая ведёт себя как GIF

Чтобы видео вело себя как GIF, используйте <video autoplay muted loop playsinline>: именно muted позволяет браузерам вообще разрешить автовоспроизведение, а playsinline не даёт iOS принудительно открывать видео в полноэкранном режиме.

<video autoplay muted loop playsinline width="640" height="360">
  <source src="clip.webm" type="video/webm">
  <source src="clip.mp4" type="video/mp4">
</video>

Политика автовоспроизведения Chrome разрешает беззвучному видео стартовать самостоятельно и блокирует автовоспроизведение со звуком до тех пор, пока посетитель не провзаимодействует с сайтом. Политика WebKit для видео на iOS допускает автовоспроизведение без жеста пользователя только для беззвучных видео или роликов без аудиодорожки, а iPhone требует playsinline, чтобы проигрывать клип на месте. Порядок источников важен, потому что браузеры не выбирают лучший <source> — они воспроизводят первый, который могут декодировать, поэтому более компактный WebM идёт первым. Такой порядок безопасен везде: таблица WebM на caniuse показывает полную поддержку в Safari 16 на macOS и в Safari на iOS начиная с 17.4, так что предостережения 2018 года об Apple и WebM больше неактуальны. Атрибуты width и height резервируют место в макете — та же забота о CLS, которую вы проявили бы к изображению.

Когда один из этих атрибутов отсутствует, сбой происходит незаметно: ни ошибки в консоли, ни иконки битого изображения — просто застывший первый кадр. Session replay показывает страницу такой, какой её действительно видел каждый пользователь, и это единственный надёжный способ поймать автовоспроизводимое видео, которое так и не запустилось в продакшене.

Как замена влияет на Largest Contentful Paint?

Замена <img> на <video> меняет то, какой элемент может стать кандидатом на LCP. Старые рекомендации гласили, что <video> без poster невидим для LCP, но это изменилось в Chrome 116: журнал изменений метрик Chromium фиксирует, что видеоэлемент теперь учитывается так же, как изображение, а его временная метка берётся с момента появления первого кадра на экране. Поэтому не добавляйте poster только ради того, чтобы «обыграть» метрику; автовоспроизводимое видео отрисовывает свой первый кадр немедленно, и постер всё равно никто не увидит. Если ваша главная анимация — самый крупный элемент, её тайминг LCP теперь зависит от того, насколько быстро приходит этот первый кадр, — ещё один повод держать файлы небольшими.

Когда GIF всё ещё выигрывает?

GIF по-прежнему выигрывает там, где вы не контролируете разметку: сообщения в чатах, почтовые клиенты и README на GitHub отображают GIF инлайн, но не встроят автовоспроизводимое видео. В таких средах переносимость важнее веса страницы, и правильное решение — сжатие GIF с потерями, а не конвертация. Опция --lossy в gifsicle (ранее — отдельный проект giflossy) меняет артефакты на размер:

gifsicle -O3 --lossy=80 -o smaller.gif input.gif

Более высокие значения потерь допускают больше артефактов и меньший размер файла; подбирайте значение, пока результат не перестанет выглядеть приемлемо, а затем отступите назад.

Подводя итоги

На любой странице, разметкой которой вы управляете, движению место в элементе <video> с двумя источниками, а не в GIF. Возьмите самый тяжёлый GIF на своём сайте, прогоните его по шагам конвертации выше и сами сравните размеры в байтах; затем внедрите разметку с четырьмя атрибутами, поставив WebM первым, и просмотрите запись реальной сессии, чтобы убедиться, что видео действительно воспроизводится.

Часто задаваемые вопросы

Можно ли отдавать только MP4 и обойтись без файла WebM?

Да. MP4 с H.264 в пиксельном формате yuv420p воспроизводится во всех современных браузерах, поэтому видеоэлемент с одним источником работает везде и ничего не ломается. Версия WebM — это оптимизация размера, а не требование совместимости: VP9 обычно даёт файл меньшего размера при сопоставимом качестве. Выпустите сначала MP4, а источник WebM добавьте выше него позже, если вес страницы всё ещё вас беспокоит.

Почему видео всё равно не воспроизводится автоматически, хотя заданы autoplay, muted, loop и playsinline?

Воспроизведение блокирует политика user agent, а не ваша разметка. Safari на iOS приостанавливает автовоспроизведение, когда устройство находится в режиме энергосбережения, и вместо этого показывает поверх кнопку воспроизведения; режимы экономии батареи или трафика в других браузерах могут вести себя аналогично. Определяйте это в JavaScript: video.play() возвращает промис, поэтому обработайте отклонение, показав элементы управления или статичное запасное изображение вместо застывшего кадра.

Работает ли loading='lazy' на элементе video?

В браузерах на основе Chromium — да. Chrome, Edge и Opera откладывают загрузку ленивого видео, получение постера и автовоспроизведение до тех пор, пока элемент не приблизится к области просмотра, и MDN документирует этот атрибут. Соответствующее дополнение к спецификации HTML находится в работе, а Firefox и WebKit оба заняли положительную позицию по этой возможности со стороны стандартов, но пока её не выпустили. Браузеры без поддержки просто игнорируют атрибут и загружают файл сразу, поэтому добавлять его к видео за пределами экрана, заменяющим GIF, сегодня безопасно.

Является ли анимированный WebP хорошим компромиссом между GIF и видео?

Иногда. Анимированный WebP работает внутри обычного элемента img, поддерживает 24-битный цвет вместо 256-цветной палитры GIF и обычно даёт файлы меньшего размера, чем эквивалентный GIF. Но он не сравнится с настоящим видеокодеком: H.264 или VP9 сжимают запись экрана значительно лучше. Используйте анимированный WebP там, где среда требует тег изображения, но принимает современные форматы, и используйте видео везде, где вы контролируете разметку.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.