Видео на сайте — самый тяжёлый контент, и все об этом знают. Поэтому ролики стараются не ставить на первый экран и не включать автозапуск. А потом видео всё равно оказывается в окне первой отрисовки: через карточку товара, «умный» компонент или фон секции. Три случая из нашей практики — все три мы нашли только разбором окна.
Это двенадцатая часть цикла «PageSpeed без мифов».
Случай 1. Видео-превью в карточках каталога
Карточки товаров показывали короткий ролик при наведении — эффектно. Внутри компонента был свой IntersectionObserver с порогом 0,5: как только карточка видна наполовину, он вызывал video.play(), чтобы ролик был готов к наведению. Карточки первого ряда видны с первого кадра — и их ролики уходили в сеть мимо всех отложенных загрузок.
В окне первой отрисовки каталога видео заняло 706 КБ из 960 — три четверти всего веса. По формуле из второй части это около 3,5 секунды к модельному LCP.
Случай 2. Автозапуск «по клику», который никто не нажимал
Блок с роликом показывал постер, а чтобы видео стартовало без двойного клика, компонент при инициализации программно «нажимал» на постер. Ролик весом 3,4 МБ начинал грузиться у каждого посетителя, даже у того, кто не долистал до блока.
Случай 3. Фоновое видео секции
Страница дилеров: фон одной из секций — зацикленный ролик. Видео подключено обычным тегом с автозапуском, и браузер начинал его качать сразу: запрос на 185-й миллисекунде при отрисовке на 283-й. 2157 КБ — почти целиком в окно.
Общее лечение
- До первой отрисовки — только постер. Картинка в правильном размере и формате (о постерах отдельная часть цикла). Атрибут
preload="none"у тегаvideoи никакогоsrc, пока не пора. - Видео подставляется после ворот из восьмой части — и только для блоков у экрана. Фоновые ролики и превью в карточках — то же самое.
- Никаких программных кликов при инициализации. Если нужен запуск с одного нажатия — подставляйте видео и запускайте его в обработчике настоящего клика.
- Учитывайте экономию трафика. Если браузер сообщает
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 по клику — об этом отдельная часть цикла.
На сайте есть видео, а оценка низкая?
Пришлите адрес — найду, какие ролики уходят в окно первой отрисовки, и сколько это стоит.
// загружаю комментарии…