Отдавай нужное изображение нужному экрану с помощью srcset и sizes, оставляй picture для художественной адаптации и освой ленивую загрузку.
Открыть этот урок в KodokonИзображения обычно составляют половину веса страницы: это твой первый рычаг производительности. Основной механизм - srcset с дескрипторами w, который объявляет реальную ширину доступных файлов, вместе с sizes, сообщающим предполагаемую ширину отображения. Ключевой момент: браузер выбирает изображение через свой сканер предзагрузки, ещё до того, как рассчитает раскладку CSS. Без sizes он предполагает 100vw и часто скачивает намного больше, чем нужно. На итоговый выбор влияет и плотность экрана: экран 2x на области в 400 px запросит файл примерно на 800 px.
<img src="harbor-800.jpg"
srcset="harbor-400.jpg 400w,
harbor-800.jpg 800w,
harbor-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="Old harbor at sunset"
width="800" height="533">С srcset/sizes решает браузер: он может отдать более лёгкий вариант в зависимости от плотности экрана или настроек экономии трафика. <picture> переворачивает логику: источник навязываешь ты через <source media> или <source type>. Оставь его для двух случаев: художественная адаптация (другая обрезка на мобильных, а не просто другой размер) и согласование формата (AVIF или WebP с запасным JPEG). Для простого изменения размера picture - лишняя сложность.
<picture>
<source media="(max-width: 600px)"
srcset="hero-square.jpg">
<source type="image/avif"
srcset="hero-wide.avif">
<img src="hero-wide.jpg" alt="Museum facade"
width="1200" height="600">
</picture>Для всего остального на странице loading="lazy" откладывает скачивание, пока изображение не приблизится к области просмотра, - нативно и без JavaScript. Дополни его decoding="async", чтобы декодирование не блокировало отрисовку, и главное - width и height: браузер вычислит соотношение сторон и зарезервирует место, что убирает сдвиги вёрстки (CLS). Для критичного изображения делай противоположное ленивой загрузке: fetchpriority="high".
<img src="gallery-01.jpg"
alt="Exhibition hall"
loading="lazy" decoding="async"
width="800" height="600">