Видео на сайте — самый тяжёлый контент, и все об этом знают. Поэтому ролики стараются не ставить на первый экран и не включать автозапуск. А потом видео всё равно оказывается в окне первой отрисовки: через карточку товара, «умный» компонент или фон секции. Три случая из нашей практики — все три мы нашли только разбором окна.

Это двенадцатая часть цикла «PageSpeed без мифов».

Случай 1. Видео-превью в карточках каталога

Карточки товаров показывали короткий ролик при наведении — эффектно. Внутри компонента был свой IntersectionObserver с порогом 0,5: как только карточка видна наполовину, он вызывал video.play(), чтобы ролик был готов к наведению. Карточки первого ряда видны с первого кадра — и их ролики уходили в сеть мимо всех отложенных загрузок.

В окне первой отрисовки каталога видео заняло 706 КБ из 960 — три четверти всего веса. По формуле из второй части это около 3,5 секунды к модельному LCP.

Случай 2. Автозапуск «по клику», который никто не нажимал

Блок с роликом показывал постер, а чтобы видео стартовало без двойного клика, компонент при инициализации программно «нажимал» на постер. Ролик весом 3,4 МБ начинал грузиться у каждого посетителя, даже у того, кто не долистал до блока.

Случай 3. Фоновое видео секции

Страница дилеров: фон одной из секций — зацикленный ролик. Видео подключено обычным тегом с автозапуском, и браузер начинал его качать сразу: запрос на 185-й миллисекунде при отрисовке на 283-й. 2157 КБ — почти целиком в окно.

Общее лечение

  1. До первой отрисовки — только постер. Картинка в правильном размере и формате (о постерах отдельная часть цикла). Атрибут preload="none" у тега video и никакого src, пока не пора.
  2. Видео подставляется после ворот из восьмой части — и только для блоков у экрана. Фоновые ролики и превью в карточках — то же самое.
  3. Никаких программных кликов при инициализации. Если нужен запуск с одного нажатия — подставляйте видео и запускайте его в обработчике настоящего клика.
  4. Учитывайте экономию трафика. Если браузер сообщает navigator.connection.saveData — фоновые и декоративные ролики не грузить вовсе.
<video muted loop playsinline preload="none" poster="/img/hero-poster.webp"
       data-src="/video/hero.mp4"></video>

<script type="module">
import afterFirstPaint from "./afterFirstPaint.js";
afterFirstPaint().then(() => {
  if (navigator.connection?.saveData) return;
  document.querySelectorAll("video[data-src]").forEach(v => {
    v.src = v.dataset.src;
    v.play().catch(() => {});
  });
});
</script>

Результат

На одном из сайтов после такой правки мобильная проверка — 97 / 99 / 99 на трёх типах страниц, а ролик начинает грузиться через 1,4–2,4 секунды — когда первый экран давно нарисован. Посетитель видит постер мгновенно и замечает, что фон «ожил», уже после.

Одинаково для всех. Видео не прячется от проверки и не отключается «для роботов» — оно просто грузится после отрисовки у любого посетителя.

А встроенные видео с YouTube или VK?

Там своя проблема: плеер тянет мегабайты скриптов ещё до нажатия «плей». Лечится картинкой-превью вместо плеера и подстановкой iframe по клику — об этом отдельная часть цикла.

На сайте есть видео, а оценка низкая?

Пришлите адрес — найду, какие ролики уходят в окно первой отрисовки, и сколько это стоит.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.