{ "index": 193, "slug": "editorial-2022-08-field-media-performance", "title": "Когда маленькая картинка тормозит страницу: как найти причину в media-слоте", "excerpt": "Изображение может быть маленьким на экране и большим в сети. Разбираем source mapping, геометрию, priority и безопасную проверку одной обратимой правки.", "contentHtml": "
Карточка товара занимает большую часть сетевого бюджета, хотя её изображение на экране имеет ширину всего 320 пикселей. Hero появляется поздно. При загрузке фильтра соседний текст прыгает вниз. В отчёте кто-то пишет: «картинка тормозит страницу» — и предлагает добавить priority или заменить файл.
\nТакой диагноз слишком широк. Ошибка может находиться в исходнике, в расчёте размера слота, в разметке, в CSS или в составе первого экрана. Если поменять CDN-вариант, размеры и атрибуты сразу, команда потеряет связь между причиной и результатом. Цена ошибки — лишний трафик, поздний полезный контент и релиз, который невозможно уверенно откатить.
\nТезис: медиа оптимизируют не по размеру файла и не по одному атрибуту. Сначала нужно описать конкретный слот, затем проверить его геометрию и выбор ресурса, после этого сопоставить намерение приложения с фактическим браузерным наблюдением. Одна гипотеза требует одной обратимой правки и повторного прогона в тех же условиях.
\nMedia-слот — это не только URL картинки. У него есть содержимое, ожидаемый размер, вариант кадрирования, плотность экрана, момент появления и место в композиции страницы. Эти решения связаны, но не заменяют друг друга.
\nСначала браузер получает HTML и видит элемент img. Атрибуты srcset и sizes дают ему набор кандидатов и ожидаемую ширину слота. Браузер сопоставляет эту подсказку с viewport и плотностью экрана, а затем выбирает ресурс. Если sizes описывает слот как 960 пикселей, хотя фактическая колонка занимает 320, браузер может выбрать слишком крупный кандидат. Малый видимый результат не означает малый сетевой расход.
Геометрия решает другую задачу. Атрибуты width и height задают intrinsic ratio изображения. Когда браузер знает соотношение сторон до загрузки, он может заранее зарезервировать место. Это снижает риск скачка соседнего контента. Но наличие атрибутов не доказывает отсутствие layout shift: контейнер, CSS, шрифт и ветка состояния могут изменить фактический layout.
Priority тоже имеет две стороны. Код может считать hero критичным и отдать ему соответствующее намерение. Это не равно доказанному порядку сетевых запросов или paint. На порядок влияют разметка, другие ресурсы, браузер, кеш и состояние страницы. Поэтому строка конфигурации — гипотеза о намерении, а trace или performance-запись — наблюдение в конкретных условиях.
\nНиже — учебный пример разметки. Он показывает контракт компонента: слот имеет размеры, набор кандидатов и текст для доступности. Пример не открывает страницу, не загружает файл и не измеряет LCP или CLS.
\n<img\n src=\"/media/product-640.avif\"\n srcset=\"/media/product-320.avif 320w,\n /media/product-640.avif 640w,\n /media/product-960.avif 960w\"\n sizes=\"(max-width: 600px) 320px, 640px\"\n width=\"640\"\n height=\"480\"\n alt=\"Чёрный рюкзак на белом фоне\"\n/>\nВ этом примере sizes должен соответствовать реальной ширине слота, а не желаемому размеру самого большого кандидата. Если карточка на узком экране занимает 320 CSS-пикселей, это нужно проверить через фактический layout. Если мобильная композиция показывает другой фрагмент изображения, одного srcset недостаточно: понадобится art direction через picture и отдельные source.
Нельзя объявлять учебный объект доказательством загрузки. Проверка вроде «в данных есть loaded» говорит только о состоянии модели. Она не подтверждает, что браузер получил response, декодировал изображение и нарисовал его. Для этого нужен отдельный прогон страницы и зафиксированные условия.
| Симптом | Возможная причина | Проверка | Действие |
|---|---|---|---|
| Маленькая картинка скачивает большой файл | Неверный sizes, отсутствует подходящий кандидат или CDN всегда отдаёт desktop-вариант | Сравнить rendered width, выбранный URL, response size и значения srcset/sizes | Исправить mapping или подсказку размера; повторить тот же viewport |
| Контент прыгает после загрузки | Нет известного ratio, контейнер меняет размер или CSS переопределяет рамку | Проверить DOM и computed layout до и после загрузки в одном сценарии | Задать корректные размеры или ratio; проверить фактический layout |
| Hero появляется поздно | Ресурс конкурирует с другими запросами, находится далеко в разметке или выбран слишком тяжёлый вариант | Снять trace с route, viewport, кешем и браузером; найти request и paint-события | Изменить только один слой: source, композицию или загрузочный путь |
| Атрибут priority не дал ожидаемого эффекта | Намерение приложения приняли за гарантию планировщика браузера | Разделить config intent и фактический порядок запросов в trace | Оставить наблюдаемый результат, проверить конкурирующие ресурсы и не добавлять второй флаг без гипотезы |
| Изображение стало резким, но объект обрезан | Поменяли resolution switching вместо art direction | Сравнить crop на целевом viewport и описание содержимого в alt | Использовать отдельный источник для композиции, сохранив fallback |
Схема полезна как ограничитель области. Поздний hero нельзя автоматически объяснить отсутствием размеров. Скачок layout нельзя исправить только сменой формата. Большой response нельзя объявить проблемой priority, пока не проверены кандидат и фактическая ширина слота.
\nsrc, кандидаты srcset, sizes, размеры, alt, предполагаемый crop и намерение critical или deferred. Называйте намерение именно намерением.sizes». Не объединяйте её с изменением CSS и priority.Размеры изображения помогают резервировать место, но не исправляют layout, который меняется из-за шрифта, рекламы, пользовательского состояния или позднего CSS. srcset и sizes уменьшают лишний download только при корректном описании слота и доступных кандидатах. picture решает art direction, но добавляет варианты, которые нужно проверить на содержимое и fallback.
Не делайте вывод о LCP по времени ответа картинки. LCP — это наблюдение о крупнейшем отрисованном элементе в конкретной загрузке. Запрос мог завершиться раньше paint, а другой элемент мог стать кандидатом. Актуальная спецификация W3C описывает API и его ограничения, но не гарантирует результат конкретной страницы.
\nЕсли trace не подтверждает гипотезу, отрицательный путь имеет конкретный вид: вернуть прежнее значение, сохранить условия прогона, отметить гипотезу как неподтверждённую и выбрать следующий слой. Если картинка всё ещё поздняя после уменьшения ресурса, проверяйте композицию страницы и конкурирующие запросы. Если скачок остаётся после добавления размеров, проверяйте реальный контейнер и CSS. Если source стал меньше, но crop ухудшился, откатите source mapping и решайте задачу art direction.
\nРазбор готов, когда для одного слота сохранены четыре вещи: воспроизводимый симптом с условиями; проверенная причина или явно отвергнутая гипотеза; одна правка с понятным откатом; повторный результат в том же сценарии. Для source должны быть видны выбранный URL и размер response. Для геометрии — фактическая рамка до и после загрузки. Для priority — разделённые intent и browser observation.
\nНе называйте работу завершённой по формулировке «стало быстрее» и не добавляйте выдуманный процент. Учебный HTML подтверждает только структуру примера. Production-вывод требует реальной страницы, реального браузерного прогона и сохранённого артефакта наблюдения. Такой критерий не обещает, что медиа больше никогда не станет проблемой. Он делает следующую ошибку обнаружимой и позволяет откатить спорную правку.
\nsrcset, sizes и art direction через picture.