Почему браузер загружает полное изображение вместо миниатюры? Потому что он скачивает ровно тот файл, который указан в разметке, а не тот, который вы видите на экране: миниатюра — это отдельный файл со своим адресом, и если в src или в CSS стоит ссылка на оригинал, уменьшение до нужного размера происходит уже после загрузки. Задание ширины и высоты через атрибуты или CSS трафик не экономит — оно лишь сжимает уже полученные данные при отрисовке.
Проверьте разметку: в src и в наборе srcset должны стоять адреса реально уменьшенных копий, а sizes — корректно описывать ширину слота на разных экранах. Браузер выбирает кандидата с учётом плотности пикселей и на экране с DPR 2–3 обоснованно возьмёт файл вдвое-втрое крупнее; при ошибке в sizes или отсутствии уменьшенных версий он уходит к оригиналу. Если миниатюра выводится через background-image или подставляется скриптом, экономии тоже не будет — загрузится тот файл, который прописан в этих правилах.
Быстрая проверка: адрес картинки в исходном коде ведёт на уменьшенную копию, а не на оригинал; sizes совпадает с реальной шириной блока; ресайз отдаёт CDN или CMS по параметрам в URL; для изображений вне первого экрана включены loading=lazy и decoding=async; в кэше не остался ранее загруженный большой файл.
