Инструменты разработчика · Кодер и декодер Base64
Встроенные изображения Base64 в CSS: когда данные: URI помогают, а когда вредят
· Почему это важно
base64 производительность
Встраивание изображения в виде данных Base64: URI удаляет запрос, но увеличивает размер файла и отменяет кэширование. В этом посте рассказывается, когда сделка того стоит, а когда отдельный файл работает быстрее.
Таблица стилей, которая выросла до сотен килобайт — привычка одной команды к встраиванию и как это отразилось на времени загрузки
Команда разработчиков решила, что встраивание маленьких значков в качестве данных Base64: URI в их CSS уменьшит количество запросов HTTP и улучшит скорость загрузки страницы. Со временем, по мере добавления новых значков, таблица стилей выросла до 400 килобайт.
В пакете CSS, который должен содержать правила стиля, теперь доминируют данные изображения. Команда измерила время загрузки и обнаружила, что страница работала медленнее, чем до встраивания, а не быстрее. Проблема стала ясна: таблица стилей размером 400 килобайта загружается при каждой загрузке страницы и кэшируется на каждой странице, тогда как если бы значки были отдельными файлами, один файл значков был бы кэширован и совместно использовался на каждой странице.
Что за данные: встроенные строки URI и почему это Base64 — синтаксис, тип носителя и штраф за размер
Добавление дополнительных страниц на сайт усугубило проблему, поскольку каждая страница снова загружает одну и ту же таблицу стилей со всеми этими встроенными изображениями. В этом посте объясняется, что такое data: URI, почему это Base64, как встраивание влияет на кеширование и производительность, а также практические правила принятия решения, когда компромисс того стоит. Данные: URL — это способ встроить ресурс непосредственно в файл HTML или CSS вместо ссылки на внешний файл. Синтаксис: data:mediaType;base64,encoded_bytes.
MediaType определяет, какой тип ресурса следует за ним, например image/svg+xml для SVG, image/png для PNG или text/plain для текста. Флаг ;base64 указывает, что полезная нагрузка имеет кодировку Base64, а не текст с процентной кодировкой. Закодированные_байты — это фактические данные. Когда браузер встречает данные: URL в свойстве href, src или background-image, он декодирует Base64 и отображает ресурс в строке. Запрос HTTP не выполняется, поскольку ресурс уже существует и встроен в родительский документ. Это экономит один или несколько запросов HTTP, что важно в мире HTTP/1.1, где каждый запрос имеет накладные расходы.
Кэширование и критический путь: почему встроенные байты загружаются снова на каждой странице, содержащей таблицу стилей
В мире HTTP/2 или HTTP/3, где множество запросов могут быть мультиплексированы по одному соединению, экономия будет меньше. Уменьшение размера кодировки Base64 является немедленным и значительным. Значок SVG размером 3 килобайт при сохранении в виде файла XML становится 4 килобайт при кодировании Base64 и внедрении в виде данных: URI. Увеличение размера 33% от кодирования должно быть добавлено к каждой странице, содержащей таблицу стилей. Если значок используется на десяти страницах, таблица стилей загружается десять раз, каждый раз включая одно и то же изображение в кодировке 4 килобайт.
Если бы значок представлял собой отдельный файл, оригинал размером 3 килобайт был бы загружен один раз и кэширован, а затем использован из кэша на всех десяти страницах. Экономический выбор для большинства значков очевиден: отдельные файлы в целом меньше. Преимущество встраивания применяется только тогда, когда значок используется ровно на одной странице или на очень небольшом количестве страниц, и значок действительно важен для этой страницы. Фавиконка, которая появляется на каждой странице, — плохой кандидат для встраивания; лучше в виде отдельного кэшированного файла.
Затраты на анализ на клиенте — насколько большие встроенные строки обрабатываются парсерами CSS и HTML, качественное описание
Одноразовую иллюстрацию, используемую только на целевой странице, может быть полезно встроить для сохранения запроса. Кэширование сводит на нет большинство преимуществ встраивания данных: URI в таблицах стилей. Таблица стилей обычно кэшируется на несколько дней или недель. Когда таблица стилей загружается, каждый встроенный в нее ресурс загружается снова, даже если в браузере уже есть это изображение в кеше. Если таблица стилей обновлена, все встроенные данные должны быть повторно проверены или повторно загружены, даже если было изменено только одно правило CSS.
Это приводит к раздуванию: изменения цветов или интервалов вызывают полную повторную загрузку таблицы стилей, включая килобайты данных изображения, которые не изменились. Отдельный файл изображения может быть кэширован независимо со своими собственными заголовками срока действия, обновляться отдельно и повторно использоваться в таблицах стилей и на страницах. Кэш браузера гораздо более эффективен, когда ресурсы представляют собой отдельные файлы, чем когда они встроены в более крупные документы. Затраты на анализ и рендеринг увеличиваются, когда большие строки Base64 встроены в таблицы стилей. Анализатор CSS должен прочитать всю таблицу стилей перед применением правил.
Рабочий пример: встраивание небольшого значка SVG в текст — вставка разметки в кодировщик и сборка данных: URI вручную
Таблица стилей размером 400 килобайт со встроенным Base64 представляет собой 400 килобайт текста, который необходимо проанализировать, прежде чем можно будет применить какие-либо правила. Анализатор HTML, отображающий страницу с большими данными: URI в атрибуте стиля или свойстве фонового изображения, должен декодировать Base64 и создать изображение, прежде чем элемент сможет отобразиться. Для простых значков SVG это тривиально. Для более сложных изображений или больших значков декодирование и рендеринг происходят в основном потоке, что потенциально блокирует интерактивность. Качественная стоимость реальна, но ее трудно измерить без профилирования.
Как правило, если размер встроенного изображения превышает несколько килобайт, отдельные файлы работают быстрее. Проработанный пример показывает точный компромисс. Возьмите простой значок стрелки SVG, 1.2 килобайт из XML. В кодировке Base64 он становится 1600 символов или около 1.6 килобайт с префиксом data: URL. Отдельное правило CSS с фоновым изображением: url(/icons/arrow.svg) добавляет, возможно, 40 bytes в таблицу стилей. Файл значка загружается один раз, кэшируется и используется повторно. Встраивание сохраняет один запрос HTTP для этого значка, но добавляет 1.6 килобайт к каждой загрузке таблицы стилей.
Практические правила, которые действуют: крошечные, важные, одноразовые ресурсы, встроенные в систему; все остальное в виде файла
Если размер таблицы стилей составляет 50 килобайт и она используется на 20 страницах, встраивание этого значка увеличивает общий объем загрузки на 32 килобайт за одно посещение сайта. Запрос HTTP, который он сохраняет, занимает максимум несколько сотен байтов служебных данных. Запрос также автоматически мультиплексируется в HTTP/2,, устраняя разницу в служебных данных. Встраивание сильно проигрывает, если только таблица стилей не маленькая, значок не большой или значок не появляется ровно на одной странице и больше нигде. Эмпирические правила, которые выдерживают тщательную проверку, ограничены и специфичны.
Крошечные, критически важные, одноразовые ресурсы могут быть встроены. Стрелка 200 байта SVG, которая появляется только на одной необычной странице, может быть встроена для экономии накладных расходов на запрос. Все остальное должно быть отдельно. Логика критического пути рендеринга имеет значение: если значок должен быть виден немедленно и каждая миллисекунда времени загрузки требует преобразования, встраивание может выиграть. Для типичных страниц с типичными иконками почти всегда лучше использовать отдельные файлы. Протестируйте оба подхода на реальных ресурсах и измерьте загрузку страницы, частоту попаданий в кеш и водопад запросов.
Что здесь не распространяется — HTTP/2 и HTTP/3 детали мультиплексирования и сжатие формата изображения.
Не думайте, что встраивание — это оптимизация без измерения. Самый простой способ получить раздутую таблицу стилей — это встраивать ее постепенно, не измеряя, действительно ли каждое добавление происходит быстрее. Кодер и декодер Base64 поможет вам принять это решение, прежде чем переходить к встраиванию. Вставьте разметку SVG или другой источник значков в инструмент в виде текста. Нажмите «Кодировать» и установите параметры для создания данных: URI. Инструмент показывает точную длину данных: URL. Сравните это с размером отдельного правила CSS и самого файла ресурса.
Подсчитайте, сколько страниц должно иметь общую таблицу стилей, чтобы обеспечить безубыточность при встраивании по сравнению с отдельными файлами. Соберите данные: URI и протестируйте их на реальной странице HTML, прежде чем зафиксировать их в таблице стилей. Если длина URI превышает несколько сотен символов, стоимость внедрения, вероятно, превысит выгоду от сохранения запроса. Используйте этот инструмент для тестирования реальных значков и ресурсов, а затем измерьте влияние на реальные показатели загрузки страницы до и после встраивания.
Вывод: встраивайте экономно и измеряйте — как кодировщик и декодер Base64 позволяет кодировать разметку SVG и видеть точный размер перед фиксацией
Производительный подход заключается в избирательном подходе к встраиванию. Значки, используемые на каждой странице или на многих страницах, представляют собой отдельные кэшированные файлы. Значки, используемые ровно на одной странице или действительно важные для первой отрисовки, могут быть встроены. Измерьте компромисс между вашими реальными ресурсами и страницами, а не следуйте общим советам. Используйте кодировщик и декодер Base64, чтобы увидеть точный размер любого встроенного ресурса, прежде чем добавлять его в таблицу стилей. Штраф за размер реален и увеличивается при каждом просмотре страницы.
Кэширование и мультиплексирование запросов сделали первоначальные преимущества встраивания менее важными. Для большинства современных приложений меньшие таблицы стилей и более высокая эффективность кэширования отдельных файлов перевешивают накладные расходы на запросы. Встраивайте экономно, измеряйте результат и доверяйте измерениям больше, чем интуиции.