Перейти к основному содержимому

Разработка 22 октября 2026г. 9 мин чтения

loading=lazy на первом экране: когда eager вредит

Мы поставили hero-картинке на главной атрибут loading="lazy" вместо привычного eager. Причина в том, что на мобильном эту же картинку скрывает display: none: у скрытого элемента нет области на экране, и браузер мог бы её вообще не трогать, а при eager он всё равно её качал. Разбираем, как на самом деле работает отложенная загрузка и почему учебниковый совет "первый экран грузите сразу" сработал у нас наоборот.

Мы поставили hero-картинке на главной атрибут loading="lazy" вместо привычного eager. Причина в том, что на мобильном эту же картинку скрывает display: none: у скрытого элемента нет области на экране, и браузер мог бы её вообще не трогать, а при eager он всё равно её качал. Разбираем, как на самом деле работает отложенная загрузка и почему учебниковый совет "первый экран грузите сразу" сработал у нас наоборот.

Правило звучит почти в каждом гайде по скорости одинаково: видимое грузим сразу, всё остальное - лениво. Мы следовали ему же, пока не сверили список сетевых запросов на телефоне с тем, что человек реально видит на узком экране. Сравнение показало: браузер честно тянул файл, которого в кадре не было ни секунды.

Как браузер решает, что грузить сразу, а что отложить

Атрибут loading="lazy" - штатная часть HTML, работает без единой строчки JavaScript. Браузер откладывает запрос картинки или iframe до момента, когда элемент подходит близко к видимой области, с небольшим запасом на прокрутку вперёд.

Разница ощутима на мобильном трафике: страница с длинной галереей не тянет разом полсотни файлов, а качает их по мере прокрутки.

С точки зрения кода это ничего не стоит. Цена появляется в другом месте: браузеру нужно сначала посчитать геометрию страницы, чтобы понять, близко элемент к экрану или нет, и только после этого принять решение о запросе.

Откуда взялось правило "первый экран грузим без задержки"

Совет привязан к метрике LCP - времени, за которое отрисовывается самый крупный видимый элемент. Подробно об этой и других метриках писали в статье Core Web Vitals 2026. Если LCP-элемент - картинка, и она отложена, браузер сначала заканчивает расчёт раскладки, потом решает, попадает ли картинка в зону загрузки, и только затем начинает её качать.

Эта ступень добавляет задержку именно тем элементам, которые и так должны появиться первыми. Правило верное ровно для одного случая: элемент реально виден при открытии страницы, без прокрутки.

Проблема в том, что "видим на макете" незаметно подменяет "виден у пользователя". У нас на десктопе hero-картинка занимает треть первого экрана, а на телефоне у той же секции другая раскладка, и картинку там решили не показывать вовсе.

Наш случай: элемент спрятан, а браузер всё равно тянет файл

display: none убирает элемент из потока документа полностью: у него нет ширины, высоты, координат, он не участвует в раскладке. Казалось логичным, что раз элемента нет на странице, то и качать его незачем.

Но с атрибутом eager это рассуждение не работает. Eager значит "начни загрузку сейчас, не дожидаясь условий". Браузер не проверяет ни видимость, ни display, ни то, попадёт ли элемент когда-нибудь в кадр - он просто выполняет команду. Картинка уходила в очередь на закачку вместе с остальными ресурсами первого экрана, хотя показать её было негде.

На мобильном трафике это чистые потери: файл занимал полосу пропускания и конкурировал за приоритет с нужными ресурсами. С loading="lazy" браузер видит, что элемент вне потока и никогда не окажется рядом с видимой областью, и запрос не отправляет.

Как проверить у себя: панель сети на узком экране

Разбор занимает пять минут. В браузере включаете эмуляцию мобильного экрана, открываете панель сети с фильтром по изображениям и перезагружаете страницу.

Дальше сравниваете два списка: что реально загрузилось и что видно на экране без прокрутки. Любой файл без соответствия на экране - кандидат на пересмотр атрибута загрузки. Проверяйте оба крайних случая, мобильный и десктопный: раскладка часто разная. Мы подробно писали про такие расхождения в статье про мобильную версию сайта.

Второй источник данных - отчёт вроде Lighthouse или PageSpeed Insights. Он прямо называет LCP-элемент для конкретного разрешения и показывает, стартовал тот сразу или с задержкой из-за очереди отложенной загрузки.

picture и srcset вместо display: none

display: none - не единственный способ показать разным экранам разный контент, и для картинок часто не лучший. Тег picture с несколькими source и условием media позволяет отдать мобильному разрешению другой файл или не отдавать картинку в принципе, ещё до того, как браузер решит её качать.

Отличие принципиальное: display: none прячет уже запрошенный элемент средствами CSS, а picture с media решает вопрос на уровне выбора ресурса, до сетевого запроса. Браузер читает условия media, находит подходящий source и запрашивает только его.

Мы разбирали адаптивную раскладку отдельно в статье про 6 брейкпойнтов и типичные провалы: там же логика, что решение "показывать или нет" правильнее принимать до загрузки ресурса, а не после неё.

Почему прятать готовое стилями - плохая привычка

display: none для целых секций - удобный инструмент, мы сами используем его для мобильного меню. Проблема не в свойстве, а в привычке применять его к тяжёлым ресурсам без учёта того, что стили и загрузка ресурсов - разные этапы обработки страницы.

CSS решает, что показать. Сеть решает, что скачать. Эти два решения не всегда успевают связаться друг с другом, особенно когда атрибут загрузки прямо говорит "качай сейчас". Правило простое: если ресурс тяжёлый - картинка, видео, встроенная карта - решение о его показе стоит принимать до того, как ресурс запрошен, а не после.

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

Карты и видео: где отложенная загрузка экономит больше всего

Встроенная карта Яндекса или Google в iframe и видеоплеер - самые тяжёлые постоянные элементы на большинстве сайтов, тяжелее почти любой картинки. Карта тянет за собой скрипты, тайлы и шрифты, видеоплеер - обвязку интерфейса и превью кадров ещё до нажатия play.

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

Отдельный случай - видео и карта в первом экране на десктопе, но скрытые на мобильном тем же приёмом display: none, что и наша hero-картинка. Логика та же: eager у скрытого iframe так же бессмысленно грузит содержимое, которое никто не увидит, только цена ошибки выше в разы из-за веса.

Чек-лист: куда какой атрибут ставить

Порядок действий, который мы теперь проходим на каждом новом проекте перед сдачей.

  1. Открыть страницу на узком экране, посмотреть панель сети, выписать всё, что грузится до первого клика.
  2. Сверить список с тем, что реально видно без прокрутки на этом разрешении.
  3. Всему, что видно сразу и на всех разрешениях, - eager, без исключений.
  4. Всему, что видно только ниже первого экрана, - lazy.
  5. Всему, что скрыто на части разрешений через display: none или media-запросы, - lazy как минимум, а по возможности переезд на picture с условием media.
  6. Для самого крупного видимого элемента первого экрана - дополнительно fetchpriority="high".
  7. Проверить отчёт по скорости после правок: LCP-элемент должен стартовать без задержки, лишние запросы - пропасть из списка сети.

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

Что решает не атрибут, а вёрстка

Атрибут loading - не переключатель "быстро или медленно", а условие запроса: eager качает сразу и безусловно, lazy - только рядом с видимой областью. У нас вёрстка прятала элемент одним способом, а загрузка была настроена другим, и эти два решения жили каждое само по себе. Простое правило на будущее: прячете тяжёлый ресурс стилями хотя бы на части разрешений - проверяйте отдельно, что происходит с его загрузкой. Иногда достаточно lazy, иногда правильнее вообще не грузить этот вариант через picture и media. Учебниковое правило "первый экран - eager" остаётся верным ориентиром, но проверять его стоит по факту в панели сети, а не по тому, что нарисовано в макете.

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

Частые вопросы

Правда ли что loading=lazy нужно ставить абсолютно всем картинкам?

Нет. Картинке, которая реально видна в первом экране на всех разрешениях, лучше оставить обычную загрузку или eager с приоритетом. Lazy имеет смысл там, где элемент либо ниже видимой области, либо скрыт вёрсткой на части разрешений, как в нашем случае с мобильной адаптацией.

Ускорит ли lazy loading картинку, которая видна сразу при открытии страницы?

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

Как понять, какая картинка на сайте реально самая тяжёлая по влиянию на скорость?

Отчёт по скорости (PageSpeed Insights, Lighthouse) прямо называет LCP-элемент страницы для конкретного разрешения. Дальше в панели сети браузера смотрите, какие файлы запрашиваются до первого действия пользователя - это быстрее и нагляднее, чем гадать по вёрстке.

Что делать, если картинка на мобильном скрыта через display: none, а на десктопе видна?

Самый надёжный вариант - не прятать картинку стилями, а не отдавать её мобильному разрешению вовсе, через media в теге picture. Если переверстать сразу не получается, промежуточное решение - loading=lazy: браузер не запросит файл, пока элемент не окажется рядом с видимой областью, а у display: none её там никогда не будет.

Нужен сайт по этой теме?

Расскажите о задаче – вернёмся с расчётом и предложением структуры.