Base64 против CSS-спрайтов: битва за производительность

Вступление

Большое количество разработчиков борится с ненужными килобайтами данных на своих веб-проектах для улучшения производительности. Уменьшение веса страниц, количества запросов, добавление скриптов и многие другие вещи влияют на скорость загрузки и отображения страниц. Разработчики используют CSS-спрайты для уменьшения количества запросов при загрузке страницы. Кодирование изображений в Base64 также используется для этих целей, и в некоторых случаях это удобней.

 

CSS-спрайты

Главная идея CSS-спрайтов заключается в объединении нескольких изображений в одно. Для показа определённой части спрайта на странице используют background-position совместно с width и height.

ПРИМЕР. CSS-спрайт от Google:

Base64 против CSS-спрайтов: битва за производительность

ПРИМЕР CSS-спрайт от Apple:

Base64 против CSS-спрайтов: битва за производительность

Преимущества:

  • объединение нескольких запросов к изображениям при загрузке в один запрос;

Недостатки:

  • трудно поддерживать и обновлять без специального инструмента, а ручное редактирование и объединение изображений в спрайты — довольно кропотливая работа;
  • большое потребление памяти (возможно, иногда и критическое) — что часто упускается из виду. Время загрузки изображений уменьшается за счёт свободного дискового пространства;
  • для спрайтов, которые не имеют пространство для отделения изображений, повышается вероятность того, что изображения могуть налагаться друг на друга.

Base64

Base64 работает с Data URI:

1

 

В CSS это выглядит таким образом:

selector {
        background: 
url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQG
DsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7) no-repeat left center;
}

В HTML-вёрстке это выглядит вот так:

<img width="16" height="16" alt="star" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNw
fjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQA
osJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />

Так вот, цель использования base64 можно достигнуть, если закодируем все маленькие изображения и поместим их в один CSS-файл. После этого, мы заменим большое количество HTTP-запросов в один — css-файл.

Преимущества:

  • возможность объдинить несколько запросов загрузки изображений в один запрос к CSS-файлу;
  • быстрое редактирование изменённого файла.

Недостатки:

  • кодирование в base64 делает размер файлов примерно на 25% больше, чем их оригинальное двоичное представление, что означает больше загружаемой информации (это может быть серьёзной проблемой для мобильных сетей);
  • data URI не поддерживается в IE6 и IE7.

Что выбрать:

Несколько месяцев назад моим ответом было бы следующее: «Использовать Base64, если нам нужно часто обновлять файл, а если не требуется обновлять, то использовать CSS-спрайты». Но сейчас есть одна важная вещь, которая даёт превосходство CSS-спрайтам — Retina-устройства. Объём готовой Retina-графики в 2 раза превышает объём обычной. Поэтому, если мы создадим 2 CSS-спрайта (retina и обычный), браузер загрузит тот спрайт, который будет использоваться. В Base64 нам нужно закодировать всю графику и мы получим 2 файла, которые будут загружаться автоматически в обоих случаях — при использовании retina- или обычного дисплея.

Если же мы хотим работать только со стилями CSS, я рекомендую CSS-спрайты.

Вот как выглядит код для Retina-устройств в CSS Media Queries:

selector {
        background-image: url(our_bg_image.png); /* will be downloaded on common displays */
}
/* Stylesheet for Retina */
@media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-device-pixel-ratio: 1.5) {
        selector {
                background-image: url(our_bg_image@2x.png); /* will be downloaded on retina displays */
        }
}

Если нам не нужна поддержка IE9 и ниже, мы можем использовать Base64 cо скриптом для retina:

<script>
var retina = window.devicePixelRatio > 1 ? true : false;
if (retina) {
        // the user has a retina display
}
else {
        // the user has a non-retina display
}
</script>

Что касается меня, то я за CSS-спрайты и CSS3 Media Queries Retina detection (для retina-устройств), потому что:

  • требуется одна технология для отображения на retina-устройствах и использование спрайтов — CSS3;
  • поддержка IE9 и ниже (мне не нужно, чтобы эти браузеры поддерживали спрайты, но как веб-разработчик — я буду лучше спать, если у меня есть сайт, который хорошо выглядит во всех браузерах).

Оригинал статьи и автор