Czy osadzanie danych obrazu tła w CSS jest dobrą czy złą praktyką Base64?

475

Patrzyłem na źródło skryptu użytkownika fatmonkey i zauważyłem w swoim css:

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

Rozumiem, że skrypt fatmonkey chciałby spakować wszystko, co może w źródle, zamiast hostować go na serwerze, co jest dość oczywiste. Ponieważ jednak wcześniej nie widziałem tej techniki, rozważałem jej zastosowanie i wydaje się ona atrakcyjna z wielu powodów:

  1. Zmniejszy liczbę żądań HTTP przy ładowaniu strony, zwiększając w ten sposób wydajność
  2. Jeśli nie ma CDN, spowoduje to zmniejszenie ruchu generowanego przez pliki cookie wysyłane wraz z obrazami
  3. Pliki CSS mogą być buforowane
  4. Pliki CSS mogą być GZIPPED

Biorąc pod uwagę, że IE6 (na przykład) ma problemy z pamięcią podręczną obrazów tła, wydaje się, że nie jest to najgorszy pomysł ...

Czy jest to dobra czy zła praktyka, dlaczego NIE WYKORZYSTUJESZ jej i jakich narzędzi użyłbyś do kodowania obrazów w base64?

aktualizacja - wyniki testów

Fajnie, ale myślę, że będzie to nieco mniej przydatne w przypadku mniejszych zdjęć.

AKTUALIZACJA: Bryan McQuade, inżynier oprogramowania w Google, pracujący nad PageSpeed, wyraził na ChromeDevSummit 2013, że dane: uris w CSS jest uważany za anty-wzorzec blokujący renderowanie w celu dostarczenia krytycznego / minimalnego CSS podczas jego rozmowy #perfmatters: Instant mobile web apps. Zobacz http://developer.chrome.com/devsummit/sessions i miej to na uwadze - rzeczywisty slajd

Dimitar Christoff
źródło
Czy masz jakieś testy? Byłoby interesujące, ile kompresja może zrekompensować fakt, że kodujesz ją w base64.
Dykam
opublikował wyniki testu, również dostępny na moim blogu fragged.org/...
Dimitar Christoff
5
Dobre pytanie. Chciałem tylko dodać, że to nie działa dla IE7 i niższych. Ale jest kilka obejść. Oto ładny artykuł na ten temat jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF
2
Dodając więcej PRO:limitów pamięci podręcznej na urządzeniach komórkowych ... CON:niektóre obrazy powinny być traktowane raczej jako treść niż prosta prezentacja, a zatem lepiej pasują do tagów HTML IMG niż obrazów tła CSS.
one.beat.consumer
1
@DimitarChristoff: Byłem fanem osadzania małych ikon w base64 ze względu na ich względną łatwość (w porównaniu z agresywnym spritingiem) i z przyjemnością zaakceptowałem rozmiar nad głową. Dzięki za wskazanie, że nie zawsze jest to przypadek (tj spakowane base64 osadzenia mogą być lepsze pod względem bezwzględnej wielkości aktywów, jak również)
ov

Odpowiedzi:

166

Nie jest dobrym pomysłem, aby zdjęcia i informacje o stylu były buforowane osobno. Również jeśli kodujesz duży obraz lub znaczną liczbę obrazów w pliku css, przeglądarka dłużej pobierze plik opuszczający witrynę bez żadnych informacji o stylu, dopóki pobieranie się nie zakończy. Dla małych obrazów, których nie zamierzasz często zmieniać, jeśli jest to dobre rozwiązanie.

w zakresie generowania kodowania base64:

kupa birck
źródło
less miał funkcję data-uri, która wstawi
Luke Page
dobrym pomysłem jest, jeśli chcesz mieć minimalną ochronę tych obrazów, aby nie były * buforowane lub mogły zostać pobrane poprzez kliknięcie prawym przyciskiem myszy -> zapisz
vsync
„Nie jest dobrym pomysłem, jeśli chcesz, aby twoje zdjęcia i informacje o stylu były buforowane osobno” - nic nie stoi na przeszkodzie, aby wszystkie obrazy były w osobnym pliku .css.
magritte
Moja praktyka i testy nie potwierdzają twojego oświadczenia. Przepraszam.
TomeeNS
55

Ta odpowiedź jest nieaktualna i nie należy jej używać.

1) Średnie opóźnienia są znacznie szybsze na urządzeniach mobilnych w 2017 roku. Https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) Multipleksy HTTP2 https://http2.github.io/faq/#why-is-http2-multiplexed

W przypadku witryn mobilnych zdecydowanie należy wziąć pod uwagę „identyfikatory URI danych”. Dostęp HTTP przez sieci komórkowe wiąże się z większym opóźnieniem na żądanie / odpowiedź. Istnieją więc przypadki użycia, w których zacinanie zdjęć jako danych w szablonach CSS lub HTML może być korzystne w mobilnych aplikacjach internetowych. Należy mierzyć użycie indywidualnie dla każdego przypadku - nie zalecam, aby identyfikatory URI danych były używane wszędzie w mobilnej aplikacji internetowej.

Pamiętaj, że przeglądarki mobilne mają ograniczenia dotyczące całkowitego rozmiaru plików, które można buforować. Limity dla iOS 3.2 były dość niskie (25 KB na plik), ale stają się coraz większe (100 KB) dla nowszych wersji Mobile Safari. Dlatego pamiętaj o całkowitym rozmiarze pliku, dołączając identyfikatory URI danych.

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

Mike Brittain
źródło
23

Jeśli odwołujesz się do tego obrazu tylko raz, nie widzę problemu z osadzeniem go w pliku CSS. Ale jeśli użyjesz więcej niż jednego obrazu lub będziesz musiał odwoływać się do niego wiele razy w swoim CSS, możesz rozważyć użycie pojedynczej mapy obrazu, zamiast tego możesz przyciąć pojedyncze obrazy (zobacz Duszki CSS ).

Gumbo
źródło
16
Oznacza to po prostu, że powinieneś mieć jedną klasę css na elemencie do odwoływania się do obrazu tła, a drugą klasę css do odwoływania się do przesunięć w tym obrazie, aby użyć tego elementu.
Duncan Beevers
4
nie powinieneś mieć żadnych klas na elementach opisujących sposób prezentacji materiału - klasy te powinny być dobrze nazwane i semantyczne (nie zawsze jest to możliwe, ale warto strzelać) Jeśli wiele elementów używa tego samego obrazu, i chciałbyś zakoduj ten obraz w CSS, po prostu zostaw obraz poza deklaracjami i użyj późniejszej reguły css, aby zadeklarować i osadzić obraz dla wielu selektorów / klas.
Adam Tolley,
1
Jeśli fotografujesz na zajęcia semantyczne, a chcesz tylko dane obrazu, możesz mieć osobny styl, który zawiera listę wszystkich odpowiednich selektorów, a następnie przesunięcia zdefiniowane w stylach dla poszczególnych selektorów. Oczywiście w przypadku bardzo małego obrazu w wielu miejscach lista selektorów może być większa niż dane ...
Leo,
Aby uniknąć wielu klas i tylko raz określić arkusz [emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
duszków
21

Jedną z rzeczy, które zasugerowałbym, są dwa osobne arkusze stylów: jeden ze zwykłymi definicjami stylów, a drugi zawierający obrazy w kodowaniu base64.

Oczywiście musisz dołączyć podstawowy arkusz stylów przed arkuszem stylów obrazu.

W ten sposób upewnisz się, że Twój regularny arkusz stylów jest pobierany i stosowany tak szybko, jak to możliwe do dokumentu, ale jednocześnie zyskujesz na zmniejszonych żądaniach HTTP i innych korzyściach, które dają ci dane uris.

ximi
źródło
1
Teoretycznie to lubię. Czy ktoś może wymyślić jakieś argumenty przeciwko?
Rob
Właśnie google google, aby dowiedzieć się, czy to dobry pomysł i przyjechałem tutaj. W moim przypadku wszystkie obrazy są tylko interfejsem użytkownika i myślałem, że to będzie dobry pomysł. Nie jestem pewien, czy jest to lepsze niż używanie duszków css, ale uważam, że łatwiej jest zarządzać, jeśli wprowadzisz zmiany w przyszłości. Czy chciałbyś wiedzieć, czy ktoś ma coś przeciwko temu?
Craig,
20

Base64 dodaje około 10% do rozmiaru obrazu po GZipped, ale to przewyższa korzyści, jeśli chodzi o telefon komórkowy. Ponieważ istnieje ogólny trend w zakresie elastycznego projektowania stron internetowych, jest wysoce zalecane.

W3C zaleca również to podejście dla urządzeń mobilnych i jeśli używasz potoku zasobów w szynach, jest to domyślna funkcja podczas kompresji css

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

Greg
źródło
dobry punkt ponownie mobilny / responsywny, choć nie jestem pewien, czy 10% skąd bierzesz te dane?
Dimitar Christoff,
3
To jest poprawne. Najwolniejszą rzeczą na każdym urządzeniu mobilnym jest otwieranie / zamykanie połączeń HTTP. Zalecane jest ich minimalizowanie.
Rafael Sanches
pomimo wyników w3, w niektórych testach zrobiłem rozmiar zdjęć zwiększony o ~ 25% :(
Fabrizio Calderan
2
Myślę, że może wzrosnąć do 33%, jeśli po prostu nie można go spakować.
Léon Pelletier,
1
na urządzeniach mobilnych 10% to nic w porównaniu do tworzenia połączeń HTTP
Rafael Sanches,
4

Nie zgadzam się z zaleceniem utworzenia osobnych plików CSS dla obrazów nieedytorskich.

Zakładając, że obrazy są do celów interfejsu użytkownika, jest to styl warstwy prezentacji, a jak wspomniano powyżej, jeśli robisz mobilny interfejs użytkownika, zdecydowanie dobrym pomysłem jest przechowywanie wszystkich stylów w jednym pliku, aby można go było buforować raz.

tim
źródło
3

W moim przypadku pozwala mi to zastosować arkusz stylów CSS bez obawy o kopiowanie powiązanych obrazów, ponieważ są one już osadzone w środku.

Rolf
źródło
3

Próbowałem stworzyć koncepcję online narzędzia analizatora CSS / HTML:

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

To może:

  • Pobierz i przeanalizuj pliki HTML / CSS, wyodrębnij elementy href / src / url
  • Wykryj kompresję (gzip) i rozmiar danych w adresie URL
  • Porównaj oryginalny rozmiar danych, rozmiar danych base64 i rozmiar danych gzipped base64
  • Konwertuj adres URL (obraz, czcionka, css, ...) na schemat URI base64 danych.
  • Policz liczbę żądań, które mogą zostać oszczędzone przez identyfikatory URI danych

Komentarze / sugestie są mile widziane.

Antonin

Antonin Foller
źródło
3

Możesz go zakodować w 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);
?>

Źródło

ucefkh
źródło
2

Przynosząc trochę użytkownikom Sublime Text 2, istnieje wtyczka, która daje kod base64, który ładujemy obrazy do ST.

O nazwie Image2base64: https://github.com/tm-minty/sublime-text-2-image2base64

PS: Nigdy nie zapisuj tego pliku wygenerowanego przez wtyczkę, ponieważ nadpisze plik i zniszczy.

Daniel Santarriaga
źródło
0

Dzięki za informacje tutaj. Uważam, że to osadzanie jest przydatne, a zwłaszcza na urządzeniach mobilnych, zwłaszcza gdy buforowany jest plik css osadzonych obrazów.

Aby ułatwić życie, ponieważ moi redaktorzy plików nie radzą sobie z tym natywnie, stworzyłem kilka prostych skryptów do edycji na laptopie / pulpicie, udostępnij je tutaj, na wypadek, gdyby były przydatne dla kogokolwiek innego. Utknąłem z php, ponieważ radzi sobie z tymi rzeczami bezpośrednio i bardzo dobrze.

W systemie Windows 8.1 powiedz ---

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

... tam jako administrator możesz ustanowić skrót do pliku wsadowego na swojej ścieżce. Ten plik wsadowy wywoła skrypt php (cli).

Następnie możesz kliknąć prawym przyciskiem myszy obraz w eksploratorze plików i wysłać do pliku wsadowego.

Ok, prośba o Admiinstartor i poczekaj, aż zamkną się czarne okna powłoki poleceń.

Następnie po prostu wklej wynik ze schowka do edytora tekstu ...

<img src="|">

lub

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

Następujące powinny być dostosowane do innych systemów operacyjnych.

Plik wsadowy ...

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

A z php.exe na twojej ścieżce, który wywołuje skrypt 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));

?>
PaulANormanNZ
źródło
0

O ile badałem,

Użyj: 1. Gdy używasz duszka svg. 2. Gdy twoje zdjęcia mają mniejszy rozmiar (maks. 200mb).

Nie używaj: 1. Gdy jesteś większy. 2. Ikony jako pliki svg. Ponieważ są już dobre i skompresowane po kompresji.

Pooja Esakkimuthu
źródło