Apakah menanamkan data gambar latar belakang ke dalam CSS sebagai Base64 praktik yang baik atau buruk?

475

Saya melihat sumber naskah pengguna greasemonkey dan memperhatikan hal-hal berikut dalam css mereka:

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

Saya dapat menghargai bahwa skrip greasemonkey ingin menggabungkan apa pun yang ada di dalam sumber sebagai lawan dari host di server, itu sudah cukup jelas. Tetapi karena saya belum pernah melihat teknik ini sebelumnya, saya mempertimbangkan penggunaannya dan tampaknya menarik karena sejumlah alasan:

  1. Ini akan mengurangi jumlah permintaan HTTP pada pemuatan halaman, sehingga meningkatkan kinerja
  2. Jika tidak ada CDN, maka itu akan mengurangi jumlah lalu lintas yang dihasilkan melalui cookie yang dikirim bersama gambar
  3. File CSS dapat di-cache
  4. File CSS dapat GZIPPED

Menimbang bahwa IE6 (misalnya) memiliki masalah dengan cache untuk gambar latar belakang, ini sepertinya bukan ide terburuk ...

Jadi, apakah ini praktik yang baik atau buruk, mengapa Anda TIDAK AKAN menggunakannya dan alat apa yang akan Anda gunakan untuk base64 menyandikan gambar?

pembaruan - hasil pengujian

Bagus, tapi itu akan sedikit kurang berguna untuk gambar yang lebih kecil, kurasa.

UPDATE: Bryan McQuade, seorang insinyur perangkat lunak di Google, bekerja pada PageSpeed, menyatakan di ChromeDevSummit 2013 bahwa data: uris di CSS dianggap sebagai anti-pola pemblokiran render untuk memberikan CSS kritis / minimal selama pembicaraannya #perfmatters: Instant mobile web apps. Lihat http://developer.chrome.com/devsummit/sessions dan ingatlah itu - slide yang sebenarnya

Dimitar Christoff
sumber
Apakah beberapa tes berjalan? Akan menarik berapa banyak kompresi dapat mengimbangi fakta Anda base64 menyandikannya.
Dykam
memposting hasil tes, juga tersedia di blog saya fragged.org/...
Dimitar Christoff
5
Pertanyaan bagus. Hanya ingin menambahkan bahwa itu tidak berfungsi untuk IE7 dan di bawah ini. Tetapi ada beberapa pekerjaan di sekitarnya. Ini adalah artikel yang bagus tentang hal ini jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF
2
Menambahkan PRO:batas cache lebih banyak pada perangkat seluler ... CON:beberapa gambar harus diperlakukan sebagai konten daripada presentasi sederhana dan dengan demikian lebih cocok untuk tag IMG HTML daripada gambar latar CSS.
one.beat.consumer
1
@ DimitarChristoff: Saya telah menjadi penggemar embedding ikon kecil dengan base64 karena relatif mudah (bila dibandingkan dengan penulisan agresif) dan senang menerima ukuran overhead. Terima kasih telah menunjukkan bahwa itu tidak selalu terjadi (mis. Menanamkan basis64 gzipped mungkin lebih baik dalam hal ukuran aset absolut juga)
Ov

Jawaban:

166

Itu bukan ide yang baik ketika Anda ingin gambar dan informasi gaya Anda di-cache secara terpisah. Juga jika Anda menyandikan gambar besar atau sejumlah besar gambar ke dalam file css Anda, browser akan membutuhkan waktu lebih lama untuk mengunduh file yang meninggalkan situs Anda tanpa informasi gaya apa pun hingga unduhan selesai. Untuk gambar kecil yang Anda tidak ingin sering berubah jika itu adalah solusi yang baik.

sejauh menghasilkan encoding base64:

kotoran seekor birck
sumber
kurang memiliki fungsi data-uri yang akan inline gambar lesscss.org/#reference
Luke Page
itu adalah ide yang baik jika Anda ingin memiliki perlindungan minimum untuk gambar-gambar itu sehingga mereka * tidak akan di-cache atau dapat diunduh dengan mengklik kanan -> save
vsync
"Ini bukan ide yang baik ketika Anda ingin gambar dan informasi gaya Anda di-cache secara terpisah" - tidak ada yang menghentikan Anda memiliki semua gambar dalam file .css terpisah.
magritte
Latihan dan tes saya tidak mengkonfirmasi pernyataan Anda. Maaf.
TomeeNS
55

Jawaban ini sudah usang dan tidak boleh digunakan.

1) Rata-rata latensi lebih cepat pada perangkat seluler pada tahun 2017. https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

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

"Data URI" harus dipertimbangkan untuk situs seluler. Akses HTTP melalui jaringan seluler hadir dengan latensi per permintaan / respons yang lebih tinggi. Jadi ada beberapa kasus penggunaan di mana gangguan gambar Anda sebagai data ke dalam CSS atau template HTML dapat bermanfaat pada aplikasi web seluler. Anda harus mengukur penggunaan berdasarkan kasus per kasus - Saya tidak menganjurkan bahwa data URI harus digunakan di mana-mana di aplikasi web seluler.

Perhatikan bahwa browser seluler memiliki batasan ukuran total file yang dapat di-cache. Batas untuk iOS 3.2 cukup rendah (25K per file), tetapi semakin besar (100K) untuk versi Mobile Safari yang lebih baru. Jadi, pastikan untuk mengawasi total ukuran file Anda saat memasukkan URI data.

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

Mike Brittain
sumber
23

Jika Anda merujuk gambar itu sekali saja, saya tidak melihat masalah untuk menanamkannya ke file CSS Anda. Tetapi begitu Anda menggunakan lebih dari satu gambar atau perlu referensi beberapa kali di CSS Anda, Anda mungkin mempertimbangkan menggunakan peta gambar tunggal sebagai gantinya Anda kemudian dapat memotong gambar tunggal dari (lihat CSS Sprite ).

Gumbo
sumber
16
Ini hanya berarti bahwa Anda harus memiliki satu kelas css pada elemen untuk referensi gambar latar belakang, dan kelas css lain untuk referensi offset ke gambar itu untuk digunakan untuk elemen itu.
Duncan Beevers
4
Anda harus memiliki kelas TIDAK pada elemen yang menggambarkan bagaimana materi disajikan - kelas-kelas tersebut harus diberi nama baik dan semantik (ini tidak selalu mungkin, tetapi bagus untuk memotret) Jika beberapa elemen menggunakan gambar yang sama, dan Anda ingin menyandikan gambar itu di CSS, biarkan gambar keluar dari deklarasi, dan gunakan aturan css kemudian untuk mendeklarasikan dan menyematkan gambar untuk beberapa penyeleksi / kelas.
Adam Tolley
1
Jika Anda memotret untuk kelas semantik dan hanya menginginkan data gambar sekali saja, Anda dapat memiliki gaya terpisah yang mencantumkan semua penyeleksi yang relevan, dan kemudian offset yang ditentukan dalam gaya per-selektor. Tentu saja, untuk gambar yang sangat kecil di banyak tempat, daftar pemilih mungkin lebih besar dari data ...
Leo
Untuk menghindari beberapa kelas dan hanya menentukan lembar sprite sekali, Anda bisa menggunakan pemilih atribut:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro
21

Salah satu hal yang saya sarankan adalah memiliki dua lembar gaya terpisah: satu dengan definisi gaya reguler Anda dan satu lagi yang berisi gambar Anda dalam pengkodean base64.

Anda harus memasukkan lembar gaya dasar sebelum lembar gambar gaya tentu saja.

Dengan cara ini Anda akan memastikan bahwa stylesheet reguler Anda diunduh dan diterapkan sesegera mungkin ke dokumen, namun pada saat yang sama Anda mendapat untung dari berkurangnya permintaan http dan data manfaat lain yang diberikan uris kepada Anda.

ximi
sumber
1
Saya suka ini dalam teori. Adakah yang bisa memikirkan argumen yang menentang?
Rob
Saya hanya mencari sendiri di Google untuk mencari tahu apakah itu ide yang bagus dan datang ke sini. Dalam kasus saya, semua gambar hanyalah barang UI dan saya berpikir ini akan menjadi ide yang bagus. Tidak yakin apakah ini lebih baik daripada menggunakan sprite css tapi saya merasa lebih mudah untuk mengelola jika Anda membuat perubahan di masa depan. Ingin tahu jika ada yang menentang ini?
Craig
20

Base64 menambahkan sekitar 10% ke ukuran gambar setelah GZipped tetapi itu lebih besar daripada manfaatnya ketika datang ke ponsel. Karena ada tren keseluruhan dengan desain web yang responsif, maka sangat disarankan.

W3C juga merekomendasikan pendekatan ini untuk seluler dan jika Anda menggunakan pipa aset di rel, ini adalah fitur default saat mengompresi css Anda

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

Greg
sumber
poin bagus kembali mobile / responsif meskipun saya tidak yakin dengan 10%, dari mana Anda mendapatkan data itu?
Dimitar Christoff
3
Ini benar. Hal paling lambat di perangkat seluler mana pun adalah membuka / menutup koneksi http. Disarankan untuk meminimalkannya.
Rafael Sanches
meskipun hasil w3, dalam beberapa tes saya melakukan ukuran gambar meningkat ~ 25% :(
Fabrizio Calderan
2
Saya kira itu bisa naik hingga 33% jika tidak mungkin untuk zip itu.
Léon Pelletier
1
pada ponsel 10% tidak seberapa dibandingkan dengan penciptaan koneksi http
Rafael Sanches
4

Saya tidak setuju dengan rekomendasi untuk membuat file CSS terpisah untuk gambar non-editorial.

Dengan asumsi gambar adalah untuk tujuan UI, itu adalah penataan lapisan presentasi, dan seperti yang disebutkan di atas, jika Anda melakukan UI seluler itu ide yang baik untuk menyimpan semua penataan dalam satu file sehingga dapat di-cache sekali.

tim
sumber
3

Dalam kasus saya, ini memungkinkan saya untuk menerapkan lembar gaya CSS tanpa khawatir menyalin gambar terkait, karena sudah tertanam di dalamnya.

Rolf
sumber
3

Saya mencoba membuat konsep online alat penganalisa CSS / HTML:

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

Bisa:

  • Unduh dan parsing file HTML / CSS, ekstrak elemen href / src / url
  • Mendeteksi kompresi (gzip) dan data ukuran pada URL
  • Bandingkan ukuran data asli, ukuran data base64 dan ukuran data base64 yang di-gzip
  • Konversikan URL (gambar, font, css, ...) ke skema URI data base64.
  • Hitung jumlah permintaan yang dapat disimpan oleh URI Data

Komentar / saran dipersilakan.

Antonin

Antonin Foller
sumber
3

Anda dapat menyandikannya dalam 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);
?>

Sumber

ucefkh
sumber
2

Membawa sedikit untuk pengguna Sublime Text 2, ada plugin yang memberikan kode base64 kita memuat gambar di ST.

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

PS: Jangan pernah menyimpan file ini yang dihasilkan oleh plugin karena itu akan menimpa file dan akan menghancurkan.

Daniel Santarriaga
sumber
0

Terima kasih atas informasinya di sini. Saya menemukan penyisipan ini berguna dan terutama untuk seluler terutama dengan file css gambar yang disematkan sedang di-cache.

Untuk membantu membuat hidup lebih mudah, karena editor file saya tidak menangani hal ini secara alami, saya membuat beberapa skrip sederhana untuk pekerjaan pengeditan laptop / desktop, bagikan di sini jika mereka ada gunanya bagi orang lain. Saya terjebak dengan php karena menangani hal-hal ini secara langsung dan sangat baik.

Di bawah Windows 8.1 katakan ---

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

... di sana sebagai Administrator, Anda dapat membuat pintasan ke file kumpulan di jalur Anda. File batch itu akan memanggil skrip php (cli).

Anda kemudian dapat mengklik kanan gambar di file explorer, dan Kirim ke kumpulan file.

Ok Admiinstartor meminta, dan menunggu windows shell perintah hitam untuk menutup.

Kemudian cukup sisipkan hasil dari clipboard ke dalam editor teks Anda ...

<img src="|">

atau

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

Mengikuti harus dapat diadaptasi untuk OS lain.

File kumpulan ...

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

Dan dengan php.exe di jalur Anda, yang memanggil skrip 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
sumber
0

Sejauh yang saya teliti,

Gunakan: 1. Saat Anda menggunakan sprite svg. 2. Saat gambar Anda berukuran lebih kecil (maks 200mb).

Jangan Pakai: 1. Saat gambar Anda lebih besar. 2. Ikon sebagai svg. Karena mereka sudah bagus dan gzip setelah kompresi.

Pooja Esakkimuthu
sumber