Веб

Base64-картинки в вебе: плюсы, минусы и скорость сайта

«Встрою все картинки прямо в код — будет меньше запросов и сайт залетает» — звучит логично, но на практике чаще выходит наоборот. Разбираемся, где встроенные Base64-изображения действительно ускоряют страницу, а где незаметно тянут её вниз — и как не выстрелить себе в ногу.

Сине-фиолетовый CSS-код в движении — встраивание картинок в стили
Встроить картинку в код легко. Вопрос в том, ускорит это сайт или замедлит. Фото: Pexels

В чём идея встроенных картинок

Обычно картинка на сайте — это отдельный файл: браузер видит <img src="logo.png"> и отправляет на сервер запрос за этим файлом. Base64-картинка устроена иначе: данные изображения зашиты прямо в HTML или CSS в виде строки data:image/png;base64,…. Отдельного файла нет, а значит, нет и отдельного запроса.

Разница видна прямо в коде. Сравните две записи одной и той же картинки:

<!-- Обычный файл: браузер идёт за ним на сервер -->
<img src="/img/logo.png">

<!-- Base64: данные уже внутри страницы -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

Если вы ещё не знакомы с самим механизмом, загляните в статью «Что такое Base64» — там разобрано, как картинка превращается в строку. А здесь поговорим именно о влиянии на скорость сайта.

Главная мысль заранее

Base64 — не «ускоритель сайта» по умолчанию. Это компромисс: вы экономите один запрос, но платите ростом размера на ~33% и потерей кеширования. Выигрыш есть только на очень мелких картинках.

Плюсы: когда это помогает

У встроенных картинок есть реальные сильные стороны — просто их область применения уже, чем кажется:

  • Нет лишнего запроса. Картинка приходит вместе с HTML или CSS — браузеру не нужно отдельно идти за файлом: искать нужный сервер и устанавливать с ним связь.
  • Картинка появляется сразу. Иконка в критическом CSS отрисуется вместе с первым экраном, без «моргания» пустого места, пока грузится файл.
  • Ничего не «отвалится». Встроенное изображение не может вернуть 404 — оно всегда на месте, потому что является частью страницы.
  • Работает в письмах. В HTML-почте внешние картинки часто блокируются, а встроенные показываются сразу. Об этом подробнее — в статье «Base64 в CSS и email».
Стена CSS-кода с градиентами и цветами — стили сайта
Маленькие иконки, зашитые в CSS, отрисовываются мгновенно — без отдельных запросов. Фото: Pexels

Минусы: где прячется подвох

Теперь обратная сторона. Чем больше картинка и чем чаще она встречается, тем сильнее минусы перевешивают плюсы:

  • Рост размера на 33%. Текстовая строка всегда тяжелее исходного файла примерно на треть. 50 иконок легко добавят странице десятки лишних килобайт.
  • Раздувание HTML и CSS. Браузер сначала должен полностью загрузить и прочитать CSS и только потом показывает страницу — поэтому огромные строки внутри прямо задерживают её появление.
  • Нагрузка на процессор. Перед показом браузер должен раскодировать Base64 обратно в байты. Для пары иконок это незаметно, для множества крупных картинок — уже ощутимая задержка.
  • Тяжело поддерживать. Поменять одну зашитую иконку — значит лезть в код и переписывать длиннющую строку. С отдельными файлами это просто замена картинки.

Главная проблема — кеширование

Это ключевой момент, из-за которого Base64 чаще вредит, чем помогает. Обычный файл картинки браузер скачивает один раз и потом берёт из кеша на всех страницах сайта и при повторных заходах. Встроенная Base64-картинка такой роскоши лишена: она живёт внутри HTML или CSS и скачивается заново каждый раз вместе со страницей.

Представьте иконку, которая используется на 12 страницах. Как отдельный файл она загрузится один раз и переиспользуется 11 раз бесплатно. Как data URI — заново на каждой из 12 страниц. Кодировка «оплачивается» снова и снова.

Посчитаем на простом примере. Пусть иконка весит 3 КБ. В Base64 она превратится в строку около 4 КБ. Пользователь, прошедший по 12 страницам, скачает эти 4 КБ двенадцать раз — почти 48 КБ трафика на одну крошечную иконку. Тот же файл с кешем обошёлся бы в 3 КБ суммарно. Разница невелика для одной иконки, но на наборе из десятков элементов и тысячах посетителей она превращается в реальный объём и реальное замедление.

Отдельный файл кешируется один раз и переиспользуется. Base64-строка скачивается заново на каждой странице — это её главная цена.

Как HTTP/2 изменил правила

Главный исторический довод за Base64 — «меньше HTTP-запросов» — родился во времена HTTP/1.1, когда каждый запрос стоил дорого: браузер мог держать лишь несколько параллельных соединений, и десятки мелких файлов реально тормозили загрузку.

Современные HTTP/2 и HTTP/3 умеют гнать десятки файлов по одному соединению почти без потерь времени. В этом мире старый аргумент почти исчез — внешний файл с кешированием обычно оказывается быстрее встроенной строки уже для картинок размером в пару килобайт.

Крупный план HTML-кода с тегами input и label
На современном HTTP внешние файлы с кешем чаще выигрывают у встроенных Base64-строк. Фото: Pexels

Простое правило выбора

Чтобы не гадать каждый раз, держите в голове ориентир по размеру:

СитуацияBase64Отдельный файл
Иконка до 5 КБ, нужна сразуДа
Картинка в критическом CSSДа
Логотип в HTML-письмеДа
Фото или баннер крупнее 10 КБНетДа
Одна иконка на многих страницахНетДа
~5 КБверхний разумный предел
+33%рост размера строки
0кеша у встроенных

Чтобы решить за 30 секунд, задайте себе три вопроса: картинка меньше 5 КБ? Она нужна на первом экране прямо сейчас? Используется ли она только на одной странице, а не на десятках? Если на все три вопроса «да» — смело встраивайте. Хотя бы одно «нет» — оставляйте отдельным файлом.

Короткий вывод: используйте Base64 точечно — для крошечных иконок, критического CSS и писем. Всё остальное оставляйте отдельными файлами. Детальное сравнение по цифрам — в статье «Base64 против обычных файлов».

Нужна Base64-строка для иконки?

Закодируйте маленькое PNG в Base64 онлайн — получите готовый data URI для вставки в CSS или HTML за пару секунд.

Конвертировать PNG в Base64

А если нужно, наоборот, достать картинку из строки — поможет Base64 → PNG. Все конвертеры собраны на странице всех форматов.

Иногда. Встроенная картинка не требует отдельного запроса к серверу, и для нескольких крошечных иконок это даёт небольшой выигрыш. Но строка тяжелее файла примерно на 33%, и она не кешируется отдельно — поэтому на больших изображениях выгода превращается в потерю.
Обычный файл картинки браузер скачивает один раз и потом берёт из кеша на всех страницах. Base64-картинка живёт внутри HTML или CSS, поэтому скачивается заново вместе со страницей при каждом заходе. Повторное использование иконки на 12 страницах означает 12-кратную загрузку одних и тех же данных.
Во многом да. Главный довод за Base64 — «меньше HTTP-запросов» — был силён на HTTP/1.1, где каждый запрос стоил дорого. HTTP/2 и HTTP/3 передают десятки файлов по одному соединению почти без накладных расходов, поэтому внешний файл с кешированием часто быстрее встроенного.
Практическое правило — мелкие изображения примерно до 5 КБ: иконки, маркеры списков, крошечные фоновые текстуры. Всё, что крупнее ~10 КБ, почти всегда лучше оставить отдельным файлом, который кешируется один раз и переиспользуется.
В критическом CSS (чтобы первый экран отрисовался без ожидания файлов), в HTML-письмах (где внешние картинки часто блокируются) и для нескольких маленьких иконок, которые нужны мгновенно. В этих сценариях экономия запроса перевешивает рост размера.