Чи вбудовані дані фонових зображень у CSS як Base64 є хорошою чи поганою практикою?


475

Я дивився на джерело користувальницького сценарію жирмоскі і помітив у своєму css:

.even { background: #fff url(data:image/gif;base64,R0lGODlhBgASALMAAOfn5+rq6uvr6+zs7O7u7vHx8fPz8/b29vj4+P39/f///wAAAAAAAAAAAAAAAAAAACwAAAAABgASAAAIMAAVCBxIsKDBgwgTDkzAsKGAhxARSJx4oKJFAxgzFtjIkYDHjwNCigxAsiSAkygDAgA7) repeat-x bottom}

Я можу оцінити, що сценарій жирного ключа хотів би зв'язати все, що може, в межах джерела, на відміну від розміщення його на сервері, це досить очевидно. Але оскільки я раніше не бачив цієї методики, я розглянув її використання і це здається привабливим з кількох причин:

  1. Це зменшить кількість запитів HTTP при завантаженні сторінки, тим самим підвищивши продуктивність
  2. Якщо немає CDN, це зменшить кількість трафіку, генерованого за допомогою файлів cookie, що надсилаються поряд із зображеннями
  3. Файли CSS можна кешувати
  4. CSS-файли можна GZIPPED

Зважаючи на те, що IE6 (наприклад) має проблеми з кешем для фонових зображень, схоже, це не найгірша ідея ...

Отже, це хороша чи погана практика, чому НЕ БУДЕ ви її використовуєте та якими інструментами ви б скористалися для base64 кодування зображень?

оновлення - результати тестування

  • тестування із зображенням: http://fragged.org/dev/map-shot.jpg - 133,6 Кб

  • тестова URL-адреса: http://fragged.org/dev/base64.html

  • виділений файл CSS: http://fragged.org/dev/base64.css - 178,1 Кб

  • Сторона сервера кодування GZIP

  • отриманий розмір, надісланий клієнту (тест компонентів YSLOW): 59,3 Кб

  • Збереження даних, що надсилаються до клієнтського браузера: 74,3 Кб

Приємно, але це буде трохи менш корисно для менших зображень, я думаю.

ОНОВЛЕННЯ: Брайан Маккуад, інженер програмного забезпечення в Google, який працює над PageSpeed, висловив на ChromeDevSummit 2013, що дані: uris в CSS вважається антидіаграмою, що блокує візуалізацію, для доставки критичних / мінімальних CSS під час розмови #perfmatters: Instant mobile web apps. Дивіться сторінку http://developer.chrome.com/devsummit/sesions і пам’ятайте про це - фактичний слайд


Деякі пробні пробіжки? Було б цікаво, наскільки стиснення може компенсувати той факт, який ви base64 кодуєте.
Dykam

Опублікував результати тесту, також скористайтеся в моєму блозі fragged.org/…
Dimitar Christoff

5
Хороше питання. Просто хотів додати, що він не працює для IE7 і нижче. Але є якась робота навколо. Ось приємна стаття про це jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
Додавання більше PRO:обмежень кешу на стільникові пристрої ... CON:деякі зображення слід розглядати як контент, а не просту презентацію, і тому вони краще підходять для тегів HTML IMG, ніж фонові зображення CSS.
one.beat.consumer

1
@DimitarChristoff: Я любив вставляти невеликі піктограми в base64 через свою відносну легкість (порівняння з агресивним спрайтом) і радий прийняв розмір накладних витрат. Дякуємо за те, що вказали, що це не завжди так (тобто вбудований gzipped base64 може бути кращим і з точки зору абсолютного розміру активів)
ов

Відповіді:


166

Це не дуже добре, коли ви хочете, щоб ваші зображення та інформація про стиль кешувалися окремо. Крім того, якщо ви зашифруєте велике зображення або значну кількість зображень у вашому файлі css, браузеру знадобиться довше, щоб завантажити файл, залишаючи ваш сайт, без будь-якої інформації про стиль, поки завантаження не завершиться. Для невеликих зображень, які ви не збираєтесь часто змінювати, якщо взагалі, це прекрасне рішення.

що стосується генерації кодування base64:


менше мали функцію data-uri, яка буде вбудовувати
Лука Сторінка

це гарна ідея, якщо ви хочете мати мінімальний захист для цих зображень, щоб вони не були * кешовані або могли бути завантажені клацанням правою кнопкою миші -> зберегти
vsync

"Недоцільно, коли ви хочете, щоб ваші зображення та інформація про стиль кешувалися окремо" - ніщо не зупинить вас, щоб усі зображення були в окремому файлі .css.
magritte

Моя практика та тести не підтверджують вашу заяву. Вибачте.
TomeeNS

55

Ця відповідь застаріла, і її не слід використовувати.

1) Середня затримка набагато швидша для мобільних пристроїв у 2017 році. Https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) HTTP2 мультиплекси https://http2.github.io/faq/#why-is-http2-multiplexed

"Можливо, URI-адреси" обов'язково слід враховувати для мобільних сайтів. Доступ до HTTP через стільникові мережі забезпечує більш високу затримку на запит / відповідь. Отож, є деякі випадки використання, коли заклинювання зображень як даних у шаблонах CSS або HTML може бути корисним для мобільних веб-додатків. Ви повинні вимірювати використання в кожному конкретному випадку - я не виступаю за те, щоб URI-файли даних використовувалися скрізь у мобільному веб-додатку.

Зауважте, що мобільні браузери мають обмеження на загальний розмір файлів, які можна кешувати. Обмеження для iOS 3.2 були досить низькими (25 Кб на файл), але збільшуються (100 К) для новіших версій Mobile Safari. Тому обов'язково стежте за загальним розміром файлу, включаючи URI даних.

http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/


23

Якщо ви посилаєтесь на це зображення лише один раз, я не бачу проблеми вставити його у свій CSS-файл. Але коли ви використовуєте більше одного зображення або вам потрібно посилатися на нього кілька разів у своєму CSS, ви можете замість цього скористатися однією картою зображень, а потім зможете обрізати свої окремі зображення (див. Спрайти CSS ).


16
Це просто означає, що у вас повинен бути один клас css на елементі для посилання на фонове зображення, а інший клас css для посилання зсувів у цьому зображенні для використання для цього елемента.
Дункан Біверс

4
у вас не повинно бути класів на елементах, які описують подання матеріалу - ці класи повинні бути добре названими та семантичними (це не завжди можливо, але добре знімати) Якщо декілька елементів використовують одне і те ж зображення, і ви хотіли б кодуйте це зображення в CSS, просто залиште зображення поза деклараціями та використовуйте пізніше правило css, щоб оголосити та вставити зображення для декількох селекторів / класів.
Адам Толлі

1
Якщо ви знімаєте для семантичних класів, а також хочете отримати дані зображення лише один раз, ви можете мати окремий стиль, у якому перераховані всі відповідні селектори, а потім зрушення, визначені у стилях кожного селектора. Звичайно, для дуже маленького зображення в багатьох місцях список селекторів може бути більшим, ніж дані ...
Лев

Щоб уникнути декількох класів і лише один раз вказати аркуш спрайта, ви можете скористатись селектором атрибутів:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

Один із речей, який я б запропонував, - це мати два окремих таблиці стилів: один із звичайними визначеннями стилів та інший, який містить ваші зображення в кодування base64.

Ви, звичайно, повинні включати базовий таблицю стилів перед таблицею стилів зображення.

Таким чином ви переконаєтесь, що ваш звичайний таблицю стилів завантажується та застосовується якнайшвидше до документа, але в той же час ви отримуєте прибуток від зменшених http-запитів та інших переваг, які дають вам урис.


1
Мені це подобається в теорії. Хтось може придумати якісь аргументи проти?
Роб

Я просто гуляв це сам, щоб дізнатися, чи це гарна ідея, і прийшов сюди. У моєму випадку зображення - це лише речі інтерфейсу, і я думав, що це буде гарною ідеєю. Не впевнений, що це краще, ніж використовувати css-спрайти, але я вважаю, що це легше керувати, якщо ви внесете зміни в майбутньому. Хотіли б дізнатися, чи є хтось проти цього?
Крейг

20

Base64 додає приблизно 10% до розміру зображення після GZipped, але це переважає переваги, коли мова йде про мобільний. Оскільки існує загальна тенденція щодо чуйного веб-дизайну, настійно рекомендується.

W3C також рекомендує такий підхід для мобільних пристроїв, і якщо ви використовуєте конвеєр активів у рейках, це функція за замовчуванням при стисненні css

http://www.w3.org/TR/mwabp/#bp-conserve-css-images


хороший пункт про мобільний / чуйний, хоча я не впевнений у 10%, звідки ви берете ці дані?
Димитар Крістофф

3
Це вірно. Найповільніше у будь-якому мобільному пристрої - це відкриття / закриття http-з'єднань. Мінімізувати їх рекомендується.
Рафаель Санчес

незважаючи на результати w3, в якомусь тесті я зробив розмір зображень збільшився на ~ 25% :(
Fabrizio Calderan

2
Я думаю, це може підняти до 33%, якщо просто неможливо це зафіксувати.
Леон Пелтьє

1
на мобільних 10% - це ніщо в порівнянні зі створенням http-зв’язків
Рафаель Санчес

4

Я не згоден з рекомендацією створювати окремі файли CSS для нередакторських зображень.

Якщо припустити, що зображення призначені для цілей користувальницького інтерфейсу, це стилізація шару презентації, і, як згадувалося вище, якщо ви робите мобільний інтерфейс, то це, безумовно, хороша ідея зберегти весь стиль в одному файлі, щоб його можна було кешувати один раз.


3

У моєму випадку це дозволяє мені застосовувати таблицю стилів CSS, не турбуючись про копіювання пов'язаних зображень, оскільки вони вже вбудовані всередину.


3

Я спробував створити онлайн-концепцію інструмента аналізатора CSS / HTML:

http://www.motobit.com/util/base64/css-images-to-base64.asp

Це може:

  • Завантажте та проаналізуйте HTML / CSS файли, витягніть елементи href / src / url
  • Виявити дані щодо стиснення (gzip) та розміру в URL-адресі
  • Порівняйте оригінальний розмір даних, розмір даних base64 та розмір даних gzipped base64
  • Перетворіть URL-адресу (зображення, шрифт, css, ...) в схему URI бази даних64.
  • Підраховуйте кількість запитів, які можна зберегти за допомогою URI даних

Коментарі / пропозиції вітаються.

Антоніна


3

Ви можете закодувати його в PHP :)

<img src="data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>">

Or display in our dynamic CSS.php file:

background: url("data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>");

1 That’s sort of a “quick-n-dirty” technique but it works. Here is another encoding method using fopen() instead of file_get_contents():

<?php // convert image to dataURL
$img_source = "feed-icon.gif"; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);
?>

Джерело


2

Додаючи трохи для користувачів Sublime Text 2, є плагін, який дає код base64, який завантажуємо зображення в ST.

Називається Image2base64: https://github.com/tm-minty/sublime-text-2-image2base64

PS: Ніколи не зберігайте цей файл, створений плагіном, оскільки він перезаписав би файл і знищив би його.


0

Дякуємо за інформацію тут. Я вважаю це вбудовування корисним, особливо для мобільних пристроїв, особливо з кешованим файлом CSS вбудованих зображень.

Щоб полегшити життя, оскільки мої файлові редактори не вирішують це, я створив декілька простих сценаріїв для роботи з редагуванням ноутбука / настільного комп’ютера, поділіться тут на випадок, якщо вони будуть корисні будь-кому іншому. Я затримався з php, оскільки він керує цими речами безпосередньо і дуже добре.

У Windows 8.1 скажіть ---

C:\Users\`your user name`\AppData\Roaming\Microsoft\Windows\SendTo

... там як адміністратор ви можете встановити ярлик до пакетного файлу на своєму шляху. Цей пакетний файл буде викликати скрипт php (cli).

Потім ви можете клацнути правою кнопкою миші зображення у файлі провідника та SendTo пакетному файлу.

Гаразд запит Admiinstartor, і зачекайте, поки вікна чорної команди оболонки закриються.

Тоді просто вставити результат з буфера обміну у свій текстовий редактор ...

<img src="|">

або

 `background-image : url("|")` 

Далі слід адаптувати для інших ОС.

Пакетний файл ...

rem @echo 0ff
rem Puts 64 encoded version of a file on clipboard
php c:\utils\php\make64Encode.php %1

І з php.exe на вашому шляху, який викликає скрипт php (cli) ...

<?php 

function putClipboard($text){
 // Windows 8.1 workaround ...

  file_put_contents("output.txt", $text);

  exec("  clip < output.txt");

}


// somewhat based on http://perishablepress.com/php-encode-decode-data-urls/
// convert image to dataURL

$img_source = $argv[1]; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);

$finfo = finfo_open(FILEINFO_MIME_TYPE); 
$dataType = finfo_file($finfo, $img_source); 


$build = "data:" . $dataType . ";base64," . $img_string; 

putClipboard(trim($build));

?>

0

Наскільки я досліджував,

Використання: 1. Коли ви використовуєте спрайт svg. 2. Коли ваші зображення мають менший розмір (макс. 200 Мб).

Не використовуйте: 1. Коли у вас великі зображення. 2. Іконки як svg. Оскільки вони вже хороші і стискаються після стиснення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.