Пожалуй, не стоит кодировать SVG с помощью Base64

Пожалуй, не стоит кодировать SVG с помощью Base64

От автора: Возможно, что вы уже слышали про схему data: URI. Это действительно замечательный способ встраивания какого-нибудь ресурса, для загрузки которого обычно потребовался бы отдельный HTTP запрос. Формат записи, использующийся в схеме data: URI, может варьироваться. Обычно вы просто указываете, к какому типу относится встраиваемый ресурс (например, image/png), точка с запятой, а затем сами данные файла.

Например:

<img src='data: ... '>

или:

.bg {
  background: url('data: ... ');
}

Для растровых изображений, таких как PNG, данные самого изображения должны быть представлены в кодировке base64. Я не супер-эксперт в данной теме, но если я правильно понял, кодировка base64 является безопасной для использования в документах типа HTML или CSS, потому что в ней используются только 64 символа, являющиеся безопасными для использования в подобного рода документах.

Слева вы видите исходные данные изображения в формате PNG, содержащие символы, которые потенциально могут нанести вред целостности HTML документа. А справа – те же самые данные, закодированные с помощью base64 и представленные в виде безопасных символов.

Пожалуй, лучше будет прочитать ответ Дэйва Маркла (Dave Markle) на сайте Stack Overflow:

Вы никогда не можете быть уверенными, что некоторые протоколы не будут интерпретировать ваши бинарные данные, как управляющие символы (например, модем), или ваши бинарные данные не могут быть испорчены в результате того, что основной протокол воспринял их, как специальную последовательность символов (например, то как FTP трактует конец строки).
Поэтому, чтобы избежать возможных проблем, разработчики кодируют бинарные данные в символы. Base64 – как раз один из таких способов кодирования.

Base64 выглядит, как бессвязный набор символов, и относительно веба такой набор обычно ассоциируется с процессом сжатия. Но он не является сжатием. На самом деле он даже немного больше исходных данных, потому что, цитируя Джона Скита (Jon Skeet) в том же обсуждении на сайте Stack Overflow:

Происходит преобразование 3 байтов данных в 4 символа, плюс может происходить добавление пробелов/других символов в конце.

Я не уверен, как на этом сказывается сжатие gzip. Но мне хочется рассмотреть здесь, что происходит с SVG. Вы можете применять data: URI для SVG:

<img src='data:image/svg+xml; ... '>
.bg {
  background: url('data:image/svg+xml; ... ');
}

В случае с SVG вы не обязаны преобразовывать данные с помощью base64. И опять же, не являясь экспертом в данной теме, думаю, что в синтаксисе SVG просто отсутствуют какие-либо «вредные» символы. Это как XML и HTML, поэтому SVG безопасно использовать в HTML. Вы можете оставить кодировку UTF-8 и вставить синтаксис svg прямо в код! Вот так:

<img src='data:image/svg+xml;utf8,<svg ... > ... </svg>'>
.bg {
  background: url('data:image/svg+xml;utf8,<svg ...> ... </svg>');
}

И поскольку мы можем так делать, и мы знаем, что base64 часто увеличивает размер данных, может быть, тогда оставить так, как есть? Да. А в качестве бонуса можно упомянуть, что чистый синтаксис svg лучше сжимается с помощью gzip, потому что он более повторяющийся, чем base64. Предположим, что вам нужны два варианта одной иконки (красный и желтый). Вы можете повторно использовать тот же SVG синтаксис, просто изменив цвет заливки. Для Gzip это будет сущий пустяк. Спасибо Тоду Паркеру (Todd Parker) за этот совет. И, кстати, такой подход используется в Grunticon, который вставляет SVG в кодировке UTF-8 с помощью data: URI в CSS код.

Тест

Чтобы протестировать этот подход, я скачал три SVG иконки с сайта IcoMoon.

Иконка cog.svg — 1,026 байтов

Иконка play.svg — 399 байтов

Иконка replay.svg — 495 байтов

Я оптимизировал их с помощь инструмента SVGO, чтобы подготовить их для вставки с помощью data: URI (пробелы были удалены, хотя я думаю, что это необязательно).

Иконка cog.svg — 685 байтов

Икока play.svg — 118 байтов

Иконка replay.svg — 212 байтов

Затем я преобразовал их с помощью конвертера base64.

Иконка cog.svg — 916 байтов — 133% от исходного размера

Иконка play.svg — 160 байтов — 136% от исходного размера

Иконка replay.svg — 283 байтов — 134% от исходного размера

По-моему, логично, не так ли? Если на каждые 3 байта приходится 4 символа, это дает нам 133%, с различным варьированием дополнительных пробелов/других символов для достижения нужного размера.

Может быть, это выглядит супер-очевидным. Но в любом случае мне хочется сказать, что если вы будете использовать data: URI для вставки SVG, у вас нет причин использовать для этого кодирование в base64.

Спасибо Мэтту Флэшену (Matt Flaschen) за его письмо, отправленное мне несколько месяцев назад. Именно оно помогло мне разобраться в данной теме.

Автор: Chris Coyier

Источник: http://css-tricks.com/

Редакция: Команда webformyself.

Курс по CSS3

Прямо сейчас изучите CSS3 с нуля!

Смотреть курс

Метки: , ,

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (2)

  1. Ольга

    Спасибо Вам за замечательные обучающие материалы. Мне, как начинающему web мастеру, видеоуроки помогли реально и во многом. С Вашей помощью я справилась со многими, как мне казалось сначала, неразрешимыми задачами.

    С Новым годом! Здоровья, счастья, творческих успехов!!!

    Ольга Орлова

    • Андрей Кудлай

      Спасибо Вам, Ольга, за отзыв и оценку нашей работы :)
      Успехов и всех благ в Новом году! ;)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree