В прошлой части мы разобрали, как loading="lazy" перестаёт работать в скрытых элементах. Но и в обычной вёрстке он не всегда делает то, что от него ждут. Три ситуации, когда ленивая загрузка не спасает, и одна, когда она прямо вредит.

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

1. Лента в одну колонку на телефоне

Ленивая загрузка Chrome начинает качать картинку задолго до экрана — с запасом в тысячи пикселей, особенно на медленной сети. Когда карточки идут в одну колонку одна под другой, в этот запас попадает десяток картинок сразу.

На мобильной ленте одного сайта до первой отрисовки уходило 774 КБ картинок. После перехода на свою загрузку — адреса в data-src, подстановка через IntersectionObserver с запасом в половину экрана и только после ворот из восьмой части — 513 КБ.

2. Слайдеры вплотную к экрану

Слайдер, начинающийся сразу под первым экраном, — в зоне ленивой загрузки с первого кадра. Его картинки грузятся вместе с первым экраном, хотя посетитель их ещё не видит.

3. Соседние слайды

Слайдер на первом экране показывает один слайд, но соседние часто уже в вёрстке, хоть и за краем. Браузер считает их «рядом» и грузит. Хуже того — сколько соседей успеет попасть в окно, зависит от скорости конкретной загрузки: на одном и том же билде окно первой отрисовки прыгало между 335 и 432 КБ. Это лишние 0,4 секунды к LCP в модели и заодно источник разброса оценки (четвёртая часть).

Лечение — отложенные адреса у всех слайдов, кроме видимого, с подстановкой после ворот и при переключении слайда. Подробно — в следующей части.

Когда lazy вредит: картинка первого экрана

Самая частая ошибка — повесить loading="lazy" на все картинки шаблоном, включая главную картинку первого экрана. Браузер откладывает её загрузку до расчёта вёрстки, и в фазах LCP появляется «задержка загрузки ресурса» — у нас 1,8 секунды.

Картинке, которая станет LCP, нужно обратное:

<link rel="preload" as="image" href="/img/hero.avif" fetchpriority="high">

<img src="/img/hero.avif" width="1600" height="900" alt="…"
     loading="eager" fetchpriority="high">
  • loading="eager" (или без атрибута) — грузить сразу;
  • fetchpriority="high" — и на прелоаде, и на самой картинке: браузер поставит её в начало очереди;
  • прелоад — если адрес картинки браузер узнаёт поздно (например, она внутри компонента, который рисуется скриптом).

Только одна-две картинки. Высокий приоритет на десяти картинках — это снова «всё срочно», и они начнут толкаться в канале с CSS и шрифтами.

Правило

Первый экран — eager и высокий приоритет. Близко под первым экраном и в слайдерах — свой контроль загрузки через ворота. Далеко внизу — обычный lazy справится. И всегда — размеры у каждой картинки (двадцать первая часть).

Не уверены, какие картинки у вас грузятся раньше времени?

Пришлите адрес — разберу окно первой отрисовки и картинки в нём.

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

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

Комментарии

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

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