Base64 olarak arka plan görüntüsü verilerini CSS'ye gömmek iyi veya kötü bir uygulama mıdır?


475

Bir greasemonkey usercript kaynağına bakıyordu ve kendi css aşağıdaki fark ettim:

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

Bir greasemonkey betiğinin bir sunucuda barındırmak yerine kaynak içinde yapabileceği her şeyi paketlemek isteyeceğini takdir edebilirim, bu yeterince açık. Ancak bu tekniği daha önce görmediğim için, kullanımını düşündüm ve birkaç nedenden dolayı çekici görünüyor:

  1. Sayfa yüklemesinde HTTP isteklerinin miktarını azaltarak performansı artırır
  2. CDN yoksa, görüntülerin yanında gönderilen çerezlerden kaynaklanan trafik miktarını azaltır.
  3. CSS dosyaları önbelleğe alınabilir
  4. CSS dosyaları GZIPPED olabilir

IE6'nın (örneğin) arka plan görüntüleri için önbellekle ilgili sorunları olduğu düşünüldüğünde, bu en kötü fikir değil gibi görünüyor ...

Peki, bu iyi veya kötü bir uygulama, neden kullanmalısınız ve görüntüleri base64 için kodlamak için hangi araçları kullanmalısınız?

güncelleme - test sonuçları

Güzel, ama daha küçük görüntüler için biraz daha az yararlı olacağını düşünüyorum.

GÜNCELLEME: Google'da PageSpeed ​​üzerinde çalışan bir yazılım mühendisi olan Bryan McQuade, ChromeDevSummit 2013'te şu verilerin olduğunu söyledi: CSS'deki uris, konuşması sırasında kritik / minimum CSS sağlamak için oluşturmayı engelleyen bir desen olarak kabul edildi #perfmatters: Instant mobile web apps. Http://developer.chrome.com/devsummit/sessions adresine bakın ve bunu aklınızda bulundurun - gerçek slayt


Bazı test çalışmaları var mı? Base64 tarafından kodladığınız gerçeği sıkıştırmanın ne kadar telafi edebileceği ilginç olurdu.
Dykam

testin sonuçları da blogumda
Dimitar Christoff

5
İyi soru. Sadece IE7 ve altı için çalışmadığını eklemek istedim. Ama etrafta bazı çalışmalar var. İşte bunun hakkında güzel bir makale jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
PRO:Hücresel cihazlara daha fazla önbellek sınırı ekleniyor ... CON:bazı görüntüler basit sunum yerine içerik olarak ele alınmalı ve bu nedenle HTML IMG etiketleri için CSS arka plan görüntülerinden daha uygun olmalıdır.
one.beat.consumer

1
@DimitarChristoff: Göreceli kolaylığı nedeniyle (agresif yazımla karşılaştırıldığında) küçük simgeleri base64 ile gömme hayranıydım ve yükü kabul etmekten mutluluk duydum. Her zaman böyle olmadığına dikkat çektiğiniz için teşekkürler (yani gzip edilmiş base64 gömme, mutlak varlık büyüklüğü açısından da daha iyi olabilir)
ov

Yanıtlar:


166

Resimlerinizin ve stil bilgilerinizin ayrı olarak önbelleğe alınmasını istediğinizde iyi bir fikir değildir. Ayrıca, css dosyanıza büyük bir resim veya önemli sayıda resim kodlarsanız, indirme işlemi tamamlanana kadar sitenizin herhangi bir stil bilgisi olmadan siteyi terk eden dosyayı indirmesi daha uzun sürer. İyi bir çözümse, sık sık değiştirmeyi düşünmediğiniz küçük görüntüler için.

base64 kodlamasını oluştururken:


daha az görüntüyü satır içine alacak bir veri-uri işlevi vardı lesscss.org/#reference
Luke Page

Eğer bu kadar bu resimler için minimum koruma istiyorsanız bu iyi bir fikir * olmaz tasarruf> - önbelleğe alınacak veya sağ tıklayarak indirilebilir olabilir
vsync

"Resimlerinizin ve stil bilgilerinizin ayrı olarak önbelleğe alınmasını istediğinizde iyi bir fikir yoktur" - tüm resimleri ayrı bir .css dosyasında bulundurmanızı engelleyecek hiçbir şey yoktur.
magritte

Uygulamam ve testlerim ifadenizi doğrulamıyor. Afedersiniz.
TomeeNS

55

Bu cevap güncel değil ve kullanılmamalıdır.

1) 2017'de mobil cihazlarda ortalama gecikme süresi çok daha hızlı. Https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) HTTP2 çoğulları https://http2.github.io/faq/#why-is-http2-multiplexed

"Veri URI'leri" kesinlikle mobil siteler için dikkate alınmalıdır. Hücresel ağlar üzerinden HTTP erişimi, istek / yanıt başına daha yüksek gecikme süresi ile gelir. Bu nedenle, görüntülerinizi CSS veya HTML şablonlarına veri olarak sıkıştırmanın mobil web uygulamalarında yararlı olabileceği bazı kullanım durumları vardır. Kullanımı duruma göre ölçmelisiniz - Veri URI'lerinin bir mobil web uygulamasının her yerinde kullanılması gerektiğini savunmuyorum.

Mobil tarayıcıların, önbelleğe alınabilecek toplam dosya boyutu konusunda sınırlamaları olduğunu unutmayın. İOS 3.2 için sınırlar oldukça düşüktü (dosya başına 25K), ancak daha yeni Mobile Safari sürümleri için daha da büyüyor (100K). Bu nedenle, veri URI'lerini eklerken toplam dosya boyutunuza dikkat edin.

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


23

Bu resme yalnızca bir kez başvurursanız, CSS dosyanıza gömmek için bir sorun görmüyorum. Ancak, birden fazla görüntü kullandığınızda veya CSS'nizde birden çok kez referans vermeniz gerektiğinde, tek bir görüntü haritası kullanmayı düşünebilirsiniz, bunun yerine tek görüntülerinizi kırpabilirsiniz (bkz. CSS Sprites ).


16
Bu, yalnızca arka plan resmine başvurmak için bir öğe üzerinde bir css sınıfınızın ve bu öğe için kullanılacak ofsetleri bu resme yönlendirmek için başka bir css sınıfınızın olması gerektiği anlamına gelir.
Duncan Beevers

4
materyalin nasıl sunulduğunu açıklayan elemanlar üzerinde NO sınıfınız olmalıdır - bu sınıflar iyi adlandırılmış ve semantik olmalıdır (bu her zaman mümkün değildir, ancak çekim yapmak iyidir) Birden fazla öğe aynı görüntüyü kullanıyorsa ve bu görüntüyü CSS'de kodlayın, görüntüyü bildirimlerin dışında bırakın ve birden çok seçici / sınıf için resmi bildirmek ve gömmek için daha sonra bir css kuralı kullanın.
Adam Tolley

1
Anlamsal sınıflar için çekim yapıyorsanız ve görüntü verilerini yalnızca bir kez istiyorsanız, tüm ilgili seçicileri listeleyen ayrı bir stiliniz ve daha sonra seçici başına stillerde tanımlanan ofsetleriniz olabilir. Tabii ki, birçok yerde çok küçük bir görüntü için, seçim listesi verilerden daha büyük olabilir ...
Leo

Birden fazla sınıftan kaçınmak ve yalnızca bir kez sprite sayfası belirtmek için bir özellik seçici kullanabilirsiniz:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

Önerebileceğim şeylerden biri iki ayrı stil sayfasına sahip olmak: Biri normal stil tanımlarınız ve diğeri de base64 kodlamasında resimlerinizi içeren.

Tabii ki görüntü stil sayfasından önce temel stil sayfasını dahil etmeniz gerekir.

Bu şekilde, normal stil sayfanızın belgeye mümkün olan en kısa sürede indirildiğinden ve uygulandığından emin olursunuz, ancak aynı zamanda azaltılmış http-isteklerinden ve veri urislerinin size sağladığı diğer avantajlardan faydalanırsınız.


1
Teoride bunu beğendim. Kimse aleyhinde bir tartışma düşünebilir mi?
Rob

İyi bir fikir olup olmadığını öğrenmek için bunu kendim araştırıyordum ve buraya geldim. Benim durumumda görüntülerin hepsi sadece kullanıcı arayüzü şeyler ve bunun iyi bir fikir olacağını düşünüyordum. Css sprite kullanmaktan daha iyi olup olmadığından emin değilim ama gelecekte değişiklik yaparsanız yönetmenin daha kolay olduğunu hissediyorum. Kimsenin buna karşı bir şey olup olmadığını bilmek ister misiniz?
Craig

20

Base64, GZip'ten sonra görüntü boyutuna yaklaşık% 10 ekler, ancak bu mobil olduğunda avantajlardan daha ağır basar. Duyarlı web tasarımı ile genel bir eğilim olduğu için şiddetle tavsiye edilir.

W3C ayrıca mobil cihazlar için bu yaklaşımı önerir ve raylarda varlık boru hattı kullanırsanız, bu, css'nizi sıkıştırırken varsayılan bir özelliktir

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


iyi nokta yeniden mobil / duyarlı% 10 emin değilim, bu verileri nereden alıyorsunuz?
Dimitar Christoff

3
Doğru. Herhangi bir mobil cihazdaki en yavaş şey http bağlantılarının açılması / kapatılmasıdır. Bunları en aza indirmeniz önerilir.
Rafael Sanches

w3 sonuçlarına rağmen, bazı testlerde görüntülerin boyutunu ~ 25% arttırdım :(
Fabrizio Calderan

2
Eğer sıkıştırmak imkansızsa% 33'e kadar yükselebilir sanırım.
Léon Pelletier

1
mobilde% 10 http bağlantılarının oluşturulmasına kıyasla hiçbir şey değildir
Rafael Sanches

4

Editöryal olmayan resimler için ayrı CSS dosyaları oluşturma önerisine katılmıyorum.

Görüntülerin UI amaçları için olduğunu varsayarsak, sunum katmanı stili ve yukarıda belirtildiği gibi, mobil kullanıcı arayüzü yapıyorsanız, tüm stilleri tek bir dosyada saklamak kesinlikle iyi bir fikirdir, böylece bir kez önbelleğe alınabilir.


3

Benim durumumda, zaten içine gömülü oldukları için ilişkili görüntüleri kopyalama konusunda endişelenmeden bir CSS stil sayfası uygulamama izin veriyor.


3

CSS / HTML çözümleyici aracının çevrimiçi konseptini oluşturmaya çalıştım:

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

Yapabilir:

  • HTML / CSS dosyalarını indirin ve ayrıştırın, href / src / url öğelerini çıkarın
  • URL'deki sıkıştırma (gzip) ve boyut verilerini algılama
  • Orijinal veri boyutunu, base64 veri boyutunu ve sıkıştırılmış base64 veri boyutunu karşılaştırın
  • URL'yi (resim, yazı tipi, css, ...) base64 veri URI şemasına dönüştürün.
  • Veri URI'leri tarafından sağlanabilecek istek sayısını sayın

Yorum / önerilerinizi bekliyoruz.

Antonin


3

PHP ile kodlayabilirsiniz :)

<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);
?>

Kaynak



0

Buradaki bilgiler için teşekkürler. Bu gömme özellikle gömülü görüntülerin css dosyası önbelleğe alınan özellikle yararlı ve mobil için buluyorum.

Dosya editör (lerim) bunu doğal olarak ele almadığından hayatı kolaylaştırmak için dizüstü / masaüstü düzenleme işleri için birkaç basit komut dosyası hazırladım, başka herhangi bir şekilde kullanmaları durumunda burada paylaşın. Ben doğrudan ve çok iyi bu şeyleri ele php ile sıkışmış var.

Windows 8.1 altında ---

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

... orada Yönetici olarak yolunuzdaki bir toplu iş dosyasına kısayol oluşturabilirsiniz. Bu toplu iş dosyası bir php (cli) betiği çağırır.

Daha sonra dosya gezgininde bir görüntüyü sağ tıklatıp batch dosyasına gönderebilirsiniz.

Yönetici yöneticisi isteği tamamlayın ve siyah komut kabuğu pencerelerinin kapanmasını bekleyin.

Ardından, panodaki sonucu metin düzenleyicinize yapıştırmanız yeterlidir ...

<img src="|">

veya

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

Aşağıdakiler diğer işletim sistemlerine uyarlanabilir olmalıdır.

Toplu iş dosyası ...

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

Ve yolunuzda php.exe ile, bu bir php (cli) komut dosyası çağırır ...

<?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

Araştırma yaptığım kadarıyla,

Kullanın: 1. Bir svg hareketli grafiği kullanırken. 2. Görüntüleriniz daha küçük boyutta olduğunda (maks. 200mb).

Kullanmayın: 1. Daha büyük görüntüler olduğunda. 2. Simgeler svg's olarak. Sıkıştırmadan sonra zaten iyi ve gziplenmiş oldukları için.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.