Я являюсь веб-разработчиком, который слишком долго закрывал глаза на проблемы с производительностью своего сайта. Пока однажды Google PageSpeed Insights не «порадовал» меня оценкой 32/100. Виновниками оказались тяжелые видео и 3D-модели, которые грузились даже тогда, когда пользователь до них не доскроллил. Так начался мой путь в мир оптимизации. Сегодня расскажу, как с помощью ленивой загрузки, Intersection Observer и кодеков нового поколения я сократил время загрузки страниц на 68% и удержал аудиторию, которая раньше уходила, не дождавшись контента.
Атрибут loading=»lazy» это только начало
Когда я впервые добавил <img loading="lazy"> для изображений, прогресс был заметен. Но с видео и WebGL-графикой всё оказалось сложнее. Оказалось, стандартный атрибут loading="lazy" для <video> работает не во всех браузерах, а 3D-модели на Three.js вообще требуют кастомных решений.
Что я сделал:
- Для встроенных видео использовал гибридный подход:
<video controls preload="none" loading="lazy" poster="placeholder.jpg"> <source src="video.mp4" type="video/mp4"> </video>
preload="none"+loading="lazy"предотвращают загрузку до момента взаимодействия пользователя. - Для 3D-графики создал систему лоадеров:
Пока модель не в области видимости, показывал низкополигональный превью (до 50 КБ вместо 5 МБ оригинальной модели).
Ошибка, которую я допустил:
Думал, что loading="lazy" достаточно. На практике для динамически добавляемого контента (например, в бесконечной ленте) он бесполезен. Тут на помощь пришёл Intersection Observer.
Intersection Observer
Когда я узнал об Intersection Observer API, это перевернуло мое представление об оптимизации. В отличие от loading="lazy", он даёт полный контроль. Можно задавать отступы для предзагрузки, работать с любыми элементами и даже анимировать появление.
Как я интегрировал его для видео:
const videoObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const video = entry.target; video.src = video.dataset.src; video.load(); videoObserver.unobserve(video); } }); }, { rootMargin: '200px' }); // Начинаем загрузку за 200px до элемента document.querySelectorAll('video[data-src]').forEach(video => { videoObserver.observe(video); });
Теперь видео грузятся только когда до них остаётся 200px скролла, а не при загрузке страницы.
Для 3D-графики на Three.js:
Использовал аналогичный подход, но с дополнительной логикой:
- При первом попадании в зону видимости загружаю 10% текстур.
- При приближении (за 500px) — остальные ресурсы.
- Если пользователь ушёл с экрана, выгружаю GLSL-шейдеры из памяти.
Как я сжал 4K-видео в 5 раз без потерь
Раньше я экспортировал видео в MP4/H.264 и удивлялся, почему файлы весят по 200 МБ. Пока не открыл для себя кодеки AV1, VP9 и HEVC:
- AV1 король сжатия.
Пример из практики:- Исходный файл: 4K, 120 сек, 1.2 ГБ (H.264).
- После кодирования в AV1: 230 МБ (качество CRF 32).
Поддерживается Chrome, Firefox, Edge. Для Safari пришлось добавить fallback в HEVC.
- WebM + VP9 идеален для коротких роликов.
Использую для фоновых видео-заставок:<video autoplay muted loop> <source src="bg-video.webm" type="video/webm"> <source src="bg-video.hevc.mp4" type="video/mp4"> </video>
- HEVC/H.265 спасение для Apple-устройств.
Хотя требует лицензирования, разница в размере поражает:
H.264 (50 МБ) → HEVC (22 МБ) с тем же битрейтом.
Мой стек инструментов для конвертации:
- FFmpeg для пакетного сжатия через скрипты.
- HandBrake интуитивное управление пресетами.
- Squoosh (от Google) оптимизация текстур для 3D-моделей.
Как объединить всё для максимальной скорости
Секрет в том, чтобы технологии работали вместе. Вот пример моего «рецепта» для страницы с 3D-портфолио:
- Первоначальная загрузка:
- Показываем статичный SVG-плейсхолдер.
- Загружаем аудио и критический CSS.
- При скролле до 1000px до секции:
- Intersection Observer инициирует предзагрузку легковесной версии модели (формат GLB с Draco-сжатием).
- Когда модель в области видимости:
- Запускаем рендеринг с низким разрешением (720p).
- Параллельно догружаем 4K-текстуры в фоне.
- Если пользователь остаётся на секции >5 сек:
- Подгружаю продвинутые шейдеры и анимации.
Результат: время полной загрузки сократилось с 11.8s до 3.4s, а отказы на мобильных устройствах упали на 40%.
Что проверить перед запуском
- Атрибуты
<video>:
preload="none",muted,playsinlineдля мобильных. - Сжатие 3D-моделей:
- Draco Compression в Blender.
- Оптимизация текстур через Basis Universal.
- Fallback для кодеков:
Всегда включайте 3 варианта источника:<video> <source src="video.av1.mp4" type="video/mp4; codecs=av01.0.05M.08"> <source src="video.hevc.mp4" type="video/mp4; codecs=hevc"> <source src="video.vp9.webm" type="video/webm"> </video>
- Тестирование в Lighthouse:
Особенно параметр «Largest Contentful Paint», он не должен включать видео/3D.
Оптимизация мультимедиа это комплекс из:
- Ленивой загрузки через Intersection Observer.
- Современных кодеков вместо устаревших форматов.
- Прогрессивного улучшения для разных устройств.
После внедрения этих методов мой сайт стал грузиться быстрее, чем приложения большинства конкурентов. И да, Google PageSpeed теперь стабильно показывает 92-95/100.
Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.


