Base64 अच्छा या बुरा अभ्यास के रूप में सीएसएस में पृष्ठभूमि छवि डेटा एम्बेड कर रहा है?


475

मैं एक ग्रीसीकेम यूजरस्क्रिप्ट के स्रोत को देख रहा था और उनकी सीएसएस में निम्नलिखित पर ध्यान दिया:

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

मैं इस बात की सराहना कर सकता हूं कि एक ग्रीसीमेक स्क्रिप्ट कुछ भी बंडल करना चाहेगा वह स्रोत के भीतर सर्वर पर होस्ट करने के लिए विरोध कर सकता है, यह स्पष्ट रूप से पर्याप्त है। लेकिन जब से मैंने इस तकनीक को पहले नहीं देखा था, मैंने इसके उपयोग पर विचार किया और यह कई कारणों से आकर्षक लगता है:

  1. यह पृष्ठ लोड पर HTTP अनुरोधों की मात्रा को कम करेगा, इस प्रकार प्रदर्शन को बढ़ाएगा
  2. यदि कोई CDN नहीं है, तो यह छवियों के साथ भेजे जा रहे कुकीज़ के माध्यम से उत्पन्न ट्रैफ़िक की मात्रा को कम कर देगा
  3. CSS फाइलों को कैश किया जा सकता है
  4. CSS फाइलें GZIPPED हो सकती हैं

यह देखते हुए कि IE6 (उदाहरण के लिए) पृष्ठभूमि छवियों के लिए कैश के साथ समस्या है, ऐसा लगता है कि यह सबसे बुरा विचार नहीं है ...

तो, क्या यह एक अच्छा या बुरा अभ्यास है, WOULDN'T आप इसका उपयोग क्यों करते हैं और आप आधार को किन-किन उपकरणों का उपयोग करके छवियों को एनकोड करेंगे?

अद्यतन - परीक्षण के परिणाम

  • छवि के साथ परीक्षण: http://fragged.org/dev/map-shot.jpg - 133.6Kb

  • परीक्षण URL: http://fragged.org/dev/base64.html

  • समर्पित सीएसएस फ़ाइल: http://fragged.org/dev/base64.css - 178.1Kb

  • GZIP एन्कोडिंग सर्वर साइड

  • ग्राहक को भेजे गए आकार (YSLOW घटकों का परीक्षण): 59.3Kb

  • क्लाइंट ब्राउजर को भेजे गए डेटा की बचत: 74.3Kb

अच्छा है, लेकिन यह छोटी छवियों के लिए थोड़ा कम उपयोगी होगा, मुझे लगता है।

अद्यतन: ब्रायन मैकक्वाडे, Google के एक सॉफ्टवेयर इंजीनियर, पेजस्पीड पर काम कर रहे, क्रोमडेवसुमिट 2013 में कहा गया कि डेटा: सीएसएस में यूरिस को अपनी बात के दौरान महत्वपूर्ण / न्यूनतम सीएसएस प्रदान करने के लिए एक रेंडर-ब्लॉकिंग-विरोधी पैटर्न माना जाता है #perfmatters: Instant mobile web appsHttp://developer.chrome.com/devsummit/session देखें और इसे ध्यान में रखें - वास्तविक स्लाइड


कुछ परीक्षण चलता है? दिलचस्प होगा कि संपीड़न इस तथ्य की भरपाई कर सकता है कि आप इसे आधार बनाते हैं।
डायकम

परीक्षण के परिणाम पोस्ट भी अपने ब्लॉग पर लाभ उठाने के fragged.org/...
दिमितार Christoff

5
अच्छा प्रश्न। बस जोड़ना चाहता था कि यह IE7 और नीचे के लिए काम नहीं करता है। लेकिन आसपास कुछ काम है। यहाँ इसके बारे में एक अच्छा लेख है jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
PRO:सेलुलर उपकरणों पर अधिक कैश सीमाएं जोड़ना ... CON:कुछ छवियों को सरल प्रस्तुति के बजाय सामग्री के रूप में माना जाना चाहिए और इस तरह सीएसएस छवि छवियों की तुलना में HTML आईएमजी टैग के लिए बेहतर फिट हैं।
one.beat.consumer

1
@DimitarChristoff: मैं अपने सापेक्ष आसानी (जब आक्रामक छिड़काव के साथ तुलना कर रहा हूं) की वजह से base64 के साथ छोटे आइकन एम्बेड करने का प्रशंसक रहा हूं और आकार के ओवरहेड को स्वीकार करने में खुशी हुई। यह इंगित करने के लिए धन्यवाद कि यह हमेशा मामला नहीं होता है (अर्थात gzipped base64 एम्बेड पूर्ण संपत्ति के आकार के मामले में बेहतर हो सकता है)
ov

जवाबों:


166

जब आप अपनी छवियों और शैली की जानकारी को अलग से कैश करना चाहते हैं तो यह एक अच्छा विचार नहीं है। यदि आप अपनी सीएसएस फ़ाइल में एक बड़ी छवि या छवियों की एक महत्वपूर्ण संख्या को सांकेतिक शब्दों में बदलना चाहते हैं, तो यह ब्राउज़र को किसी भी शैली की जानकारी के बिना आपकी साइट को छोड़ने वाली फ़ाइल को डाउनलोड करने में अधिक समय लगेगा जब तक कि डाउनलोड पूरा नहीं हो जाता। छोटी छवियों के लिए जिन्हें आप अक्सर बदलने का इरादा नहीं रखते हैं अगर कभी यह एक अच्छा समाधान है।

जहाँ तक बेस 64 एनकोडिंग बनाने की बात है:


कम में एक डेटा-उरी फ़ंक्शन था जो एक छवि को इनलाइन करेगा। ifcss.org/#reference
ल्यूक पेज

यह एक अच्छा विचार है यदि आप उन छवियों के लिए न्यूनतम सुरक्षा रखना चाहते हैं तो वे * कैश नहीं होंगे या राइट-क्लिक करके डाउनलोड किया जा सकता है -> सहेजें
vsync

"यह एक अच्छा विचार नहीं है जब आप चाहते हैं कि आपकी छवियां और शैली की जानकारी अलग-अलग कैश की जाए" - आपको अलग-अलग .css फ़ाइल में सभी छवियों को रोकने के लिए कुछ भी नहीं है।
मैगेट्रेट

मेरे अभ्यास और परीक्षण आपके कथन की पुष्टि नहीं करते हैं। माफ़ करना।
टोमेन्स

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

मोबाइल साइटों के लिए "डेटा यूआरआई" पर निश्चित रूप से विचार किया जाना चाहिए। सेलुलर नेटवर्क पर HTTP एक्सेस अनुरोध / प्रतिक्रिया के अनुसार उच्च विलंबता के साथ आता है। तो कुछ उपयोग के मामले हैं जहां सीएसएस या HTML टेम्प्लेट में डेटा के रूप में आपकी छवियों को जाम करना मोबाइल वेब ऐप पर फायदेमंद हो सकता है। आपको केस-दर-मामला आधार पर उपयोग को मापना चाहिए - मैं इस बात की वकालत नहीं कर रहा हूं कि मोबाइल वेब ऐप में हर जगह डेटा यूआरआई का उपयोग किया जाना चाहिए।

ध्यान दें कि मोबाइल ब्राउज़रों की कुल आकार की फ़ाइलों की सीमाएँ हैं जिन्हें कैश किया जा सकता है। IOS 3.2 के लिए सीमाएं बहुत कम (25K प्रति फ़ाइल) थीं, लेकिन मोबाइल सफारी के नए संस्करणों के लिए बड़ी (100K) हो रही हैं। इसलिए डेटा URI को शामिल करते समय अपने कुल फ़ाइल आकार पर नज़र रखना सुनिश्चित करें।

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


23

यदि आप उस छवि को केवल एक बार संदर्भित करते हैं, तो मुझे आपकी CSS फ़ाइल में एम्बेड करने के लिए कोई समस्या नहीं दिखती है। लेकिन एक बार जब आप एक से अधिक छवि का उपयोग करते हैं या अपने सीएसएस में इसे कई बार संदर्भित करने की आवश्यकता होती है, तो आप इसके बजाय एकल छवि मानचित्र का उपयोग करने पर विचार कर सकते हैं (फिर सीएसएस स्प्राइट्स देखें )।


16
इसका सिर्फ इतना मतलब है कि आपके पास पृष्ठभूमि छवि को संदर्भित करने के लिए एक तत्व पर एक सीएसएस वर्ग होना चाहिए, और उस तत्व के लिए उपयोग करने के लिए उस छवि में ऑफसेट संदर्भित करने के लिए एक और सीएसएस वर्ग।
डंकन बीवर

4
आपके पास तत्वों पर कोई कक्षाएं नहीं होनी चाहिए जो यह बताती हैं कि सामग्री कैसे प्रस्तुत की जाती है - उन कक्षाओं को अच्छी तरह से नाम दिया जाना चाहिए और शब्दार्थ (यह हमेशा संभव नहीं है, लेकिन शूट करने के लिए अच्छा है) यदि कई तत्व एक ही छवि का उपयोग करते हैं, और आप चाहेंगे सीएसएस में उस छवि को एनकोड करें, बस छवि को घोषणाओं से बाहर छोड़ दें, और एकाधिक चयनकर्ताओं / वर्गों के लिए छवि को घोषित करने और एम्बेड करने के लिए बाद के सीएसएस नियम का उपयोग करें।
एडम टोली

1
यदि आप सिमेंटिक कक्षाओं के लिए शूटिंग कर रहे हैं और छवि डेटा बस एक बार चाहते हैं, तो आपके पास एक अलग शैली हो सकती है जो सभी प्रासंगिक चयनकर्ताओं को सूचीबद्ध करती है , और फिर प्रति-चयनकर्ता शैलियों में परिभाषित ऑफ़सेट्स। बेशक, बहुत सी जगहों पर बहुत छोटी छवि के लिए, चयनकर्ता सूची डेटा से बड़ी हो सकती है ...
लियो

कई वर्गों से बचने के लिए और केवल एक बार एक स्प्राइट शीट निर्दिष्ट करने के लिए, आप एक विशेषता चयनकर्ता का उपयोग कर सकते हैं:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
चिनोटो वोक्रो

21

जिन चीजों के बारे में मैं सुझाव दूंगा उनमें से एक दो अलग-अलग स्टाइलशीट हैं: एक आपकी नियमित शैली की परिभाषाओं के साथ और दूसरा वह जिसमें आपकी छवियां बेस 64 एनकोडिंग में हैं।

आपको बेस स्टाइलशीट को पाठ्यक्रम की छवि स्टाइलशीट से पहले शामिल करना होगा।

इस तरह आप आश्वस्त होंगे कि आप नियमित स्टाइलशीट डाउनलोड कर रहे हैं और जल्द से जल्द दस्तावेज़ में लागू कर दिए गए हैं, फिर भी उसी समय आपको कम http-request और अन्य लाभ डेटा-यूरीस से लाभ मिलता है।


1
मुझे यह सिद्धांत में पसंद है। क्या कोई भी किसी भी तर्क के खिलाफ सोच सकता है?
रोब

मैं सिर्फ यह पता लगाने के लिए खुद को गोग्लिंग कर रहा था कि क्या यह एक अच्छा विचार है और यहां आ गया। मेरे मामले में चित्र सभी यूआई सामान हैं और मैं सोच रहा था कि यह एक अच्छा विचार होगा। सुनिश्चित नहीं है कि अगर यह सीएसएस स्प्राइट्स का उपयोग करने से बेहतर है, लेकिन मुझे लगता है कि यदि आप भविष्य में बदलाव करते हैं तो प्रबंधन करना आसान है। यह जानना अच्छा लगेगा कि क्या किसी के पास इसके खिलाफ कुछ भी है?
क्रेग

20

बेस 64 GZipped के बाद छवि के आकार में लगभग 10% जोड़ता है लेकिन जब मोबाइल की बात आती है तो यह लाभ को कम कर देता है। चूंकि उत्तरदायी वेब डिज़ाइन के साथ एक समग्र प्रवृत्ति है, यह अत्यधिक अनुशंसित है।

W3C भी मोबाइल के लिए इस दृष्टिकोण की सिफारिश करता है और यदि आप रेल में परिसंपत्ति पाइपलाइन का उपयोग करते हैं, तो यह आपकी सीएसएस को संकुचित करते समय एक डिफ़ॉल्ट विशेषता है।

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


अच्छा बिंदु पुनः मोबाइल / उत्तरदायी हालांकि मैं 10% के बारे में सुनिश्चित नहीं हूं, आपको वह डेटा कहां से मिलेगा?
दिमित्र क्रिस्टोफ

3
यह सही है। किसी भी मोबाइल डिवाइस में सबसे धीमी चीज http कनेक्शन का खुला / बंद होना है। उन्हें कम से कम करने की सिफारिश की गई है।
राफेल सांचे

w3 परिणामों के बावजूद, कुछ परीक्षण में मैंने छवियों का आकार ~ 25% बढ़ा दिया :(
Fabrizio Calderan

2
मुझे लगता है कि यह 33% तक बढ़ सकता है अगर इसे जिप करना असंभव है।
लीनो पेलेटियर

1
मोबाइल पर 10% http कनेक्शन के निर्माण की तुलना में कुछ भी नहीं है
राफेल सांचे

4

मैं गैर-संपादकीय छवियों के लिए अलग सीएसएस फाइलें बनाने की सिफारिश से असहमत हूं।

मान लें कि छवियां UI उद्देश्यों के लिए हैं, तो यह प्रस्तुति परत स्टाइल है, और जैसा कि ऊपर उल्लेख किया गया है, यदि आप मोबाइल UI की अपनी निश्चित रूप से एक ही फाइल में सभी स्टाइल रखने के लिए एक अच्छा विचार है, तो इसे एक बार कैश किया जा सकता है।


3

मेरे मामले में यह मुझे संबंधित छवियों को कॉपी करने के बारे में चिंता किए बिना सीएसएस स्टाइलशीट लागू करने की अनुमति देता है, क्योंकि वे पहले से ही अंदर एम्बेडेड हैं।


3

मैंने CSS / HTML विश्लेषक टूल की ऑनलाइन अवधारणा बनाने की कोशिश की:

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

यह:

  • एचटीएमएल / सीएसएस फ़ाइलों को डाउनलोड और पार्स करें, href / src / url एलिमेंट्स निकालें
  • सम्पीडन (gzip) का पता लगाएँ और URL पर डेटा आकार दें
  • मूल डेटा आकार, आधार 64 डेटा आकार और gzipped base64 डेटा आकार की तुलना करें
  • URL (छवि, फ़ॉन्ट, css, ...) को एक बेस 64 डेटा URI स्कीम में बदलें।
  • डेटा 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

उदात्त पाठ 2 के उपयोगकर्ताओं के लिए थोड़ा सा लाना, एक प्लगइन है जो आधार 64 कोड देता है जो हम एसटी में छवियों को लोड करते हैं।

कॉल की गई इमेज 2base64: https://github.com/tm-minty/sublime-text-2-image2base64

PS: प्लगइन द्वारा उत्पन्न इस फ़ाइल को कभी भी न सहेजें क्योंकि यह फ़ाइल को अधिलेखित कर देगा और नष्ट कर देगा।


0

जानकारी के लिए यहां धन्यवाद। मुझे यह एम्बेडिंग उपयोगी और विशेष रूप से मोबाइल के लिए विशेष रूप से एम्बेडेड छवियों की सीएसएस फ़ाइल के साथ कैश की जा रही है।

जीवन को आसान बनाने में मदद करने के लिए, जैसा कि मेरे फ़ाइल संपादक (ओं) ने मूल रूप से इसे संभाल नहीं किया है, मैंने लैपटॉप / डेस्कटॉप संपादन कार्य के लिए कुछ सरल लिपियों का निर्माण किया है, यहाँ साझा करें यदि वे किसी अन्य के लिए उपयोग करते हैं। मैं php के साथ फंस गया हूं क्योंकि यह इन चीजों को सीधे और बहुत अच्छी तरह से संभाल रहा है।

विंडोज 8.1 के तहत कहते हैं ---

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

... वहाँ एक प्रशासक के रूप में आप अपने रास्ते में एक बैच फ़ाइल के लिए एक शॉर्टकट स्थापित कर सकते हैं। वह बैच फ़ाइल php (cli) स्क्रिप्ट कहेगी।

फिर आप फ़ाइल एक्सप्लोरर में एक छवि पर राइट क्लिक कर सकते हैं, और सेंड बैच सकते हैं।

ठीक है 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. जब आपकी छवियां कम आकार (अधिकतम 200mb) की हों।

उपयोग न करें: 1. जब आप बड़े चित्र हों। 2. svg के रूप में प्रतीक। के रूप में वे पहले से ही अच्छे हैं और संपीड़न के बाद gzipped।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.