การฝังข้อมูลภาพพื้นหลังลงใน CSS เป็นหลักปฏิบัติที่ดีหรือไม่ดี Base64 หรือไม่?


475

ฉันดูที่แหล่งที่มาของ userscript greasemonkey และสังเกตเห็นสิ่งต่อไปนี้ใน CSS:

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

ฉันสามารถชื่นชมได้ว่าสคริปต์ greasemonkey ต้องการรวมสิ่งที่สามารถทำได้ภายในแหล่งที่มาแทนที่จะเป็นโฮสต์บนเซิร์ฟเวอร์นั่นชัดเจนเพียงพอ แต่ก่อนหน้านี้ฉันไม่เคยเห็นเทคนิคนี้เลยฉันจึงพิจารณาการใช้งานและดูเหมือนว่าจะมีเหตุผลหลายประการ:

  1. มันจะลดปริมาณของคำขอ HTTP ในการโหลดหน้าซึ่งจะช่วยเพิ่มประสิทธิภาพ
  2. หากไม่มี CDN ก็จะลดปริมาณการรับส่งข้อมูลที่สร้างขึ้นจากคุกกี้ที่ถูกส่งไปพร้อมกับรูปภาพ
  3. ไฟล์ CSS สามารถแคชได้
  4. ไฟล์ CSS สามารถเป็น GZIPPED

เมื่อพิจารณาว่า IE6 (เช่น) มีปัญหากับแคชสำหรับภาพพื้นหลังดูเหมือนว่าไม่ใช่ความคิดที่เลวร้ายที่สุด ...

นี่เป็นวิธีปฏิบัติที่ดีหรือไม่ดีทำไมคุณไม่ใช้และคุณจะใช้เครื่องมือใดในการเข้ารหัสภาพที่ base64

อัพเดท - ผลการทดสอบ

  • การทดสอบด้วยภาพ: http://fragged.org/dev/map-shot.jpg - 133.6Kb

  • URL ทดสอบ: http://fragged.org/dev/base64.html

  • ไฟล์ CSS เฉพาะ: http://fragged.org/dev/base64.css - 178.1Kb

  • ฝั่งเซิร์ฟเวอร์การเข้ารหัส GZIP

  • ขนาดผลลัพธ์ส่งไปยังลูกค้า (ทดสอบส่วนประกอบ YSLOW): 59.3Kb

  • การบันทึกข้อมูลที่ส่งไปยังเบราว์เซอร์ไคลเอ็นต์ของ: 74.3Kb

ดีมาก แต่มันจะมีประโยชน์น้อยลงสำหรับภาพเล็ก ๆ ฉันว่า

UPDATE: ไบรอัน McQuade, วิศวกรซอฟต์แวร์ที่ Google ทำงานใน PageSpeed แสดงที่ ChromeDevSummit 2013 ว่าข้อมูล: ยูริใน CSS ถือว่าเป็นบล็อกการแสดงผลป้องกันรูปแบบสำหรับการส่งมอบที่สำคัญ / CSS #perfmatters: Instant mobile web appsน้อยที่สุดในระหว่างการพูดคุยของเขา ดูhttp://developer.chrome.com/devsummit/sessionsและจำไว้ - สไลด์จริง


มีการทดสอบบ้างไหม จะน่าสนใจเท่าไหร่การบีบอัดสามารถชดเชยความจริงที่คุณ base64 เข้ารหัส
Dykam

โพสต์ผลการทดสอบและมีประโยชน์ในบล็อกของฉันfragged.org/
Dimitar Christoff

5
คำถามที่ดี. แค่อยากจะเพิ่มว่ามันไม่ทำงานสำหรับ IE7 และด้านล่าง แต่ก็มีบางงานที่ต้องแก้ไข นี่เป็นบทความที่ดีเกี่ยวกับเรื่องนี้jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
การเพิ่มPRO:ขีด จำกัด แคชบนอุปกรณ์มือถือ ... CON:รูปภาพบางภาพควรถือเป็นเนื้อหาแทนที่จะเป็นการนำเสนอแบบง่ายและเหมาะสำหรับแท็ก IMG HTML มากกว่าภาพพื้นหลัง CSS
one.beat.consumer

1
@DimitarChristoff: ฉันเป็นแฟนตัวยงของการฝังไอคอนขนาดเล็กที่มี base64 เพราะความสะดวกสัมพัทธ์ (เมื่อเปรียบเทียบกับการ spriting เชิงรุก) และยินดีที่จะยอมรับขนาดของค่าใช้จ่าย ขอบคุณสำหรับการชี้ให้เห็นว่ามันไม่เสมอกรณี (เช่น gzipped base64 ฝังอาจจะดีกว่าในแง่ของขนาดสินทรัพย์ที่แน่นอนเช่นกัน)
OV

คำตอบ:


166

ไม่ใช่ความคิดที่ดีเมื่อคุณต้องการให้แคชรูปภาพและข้อมูลสไตล์แยกจากกัน นอกจากนี้หากคุณเข้ารหัสภาพขนาดใหญ่หรือรูปภาพจำนวนมากในไฟล์ css ของคุณจะใช้เวลานานกว่าเบราว์เซอร์ในการดาวน์โหลดไฟล์ออกจากเว็บไซต์ของคุณโดยไม่มีข้อมูลสไตล์จนกว่าการดาวน์โหลดจะเสร็จสมบูรณ์ สำหรับรูปภาพขนาดเล็กที่คุณไม่ต้องการเปลี่ยนแปลงบ่อยๆหากเป็นโซลูชันที่ดี

เท่าที่สร้างการเข้ารหัส base64:


น้อยกว่ามีฟังก์ชั่น data-uri ที่จะแทรกรูปภาพlesscss.org/#reference
ลุคหน้า

เป็นความคิดที่ดีหากคุณต้องการการป้องกันขั้นต่ำสำหรับรูปภาพเหล่านั้นดังนั้นจะไม่ถูกแคช*หรือสามารถดาวน์โหลดได้โดยคลิกขวา -> บันทึก
vsync

"ไม่ใช่ความคิดที่ดีเมื่อคุณต้องการให้แคชรูปภาพและข้อมูลสไตล์ของคุณแยกจากกัน" - ไม่มีสิ่งใดที่จะหยุดคุณมีภาพทั้งหมดในไฟล์. css แยกต่างหาก
magritte

การปฏิบัติและการทดสอบของฉันไม่ได้ยืนยันคำสั่งของคุณ ขอโทษ
TomeeNS

55

คำตอบนี้ล้าสมัยและไม่ควรใช้

1) เวลาเฉลี่ยในการตอบสนองเร็วขึ้นมากบนมือถือในปี 2560 https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

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

"URI ของข้อมูล" ควรได้รับการพิจารณาสำหรับไซต์มือถืออย่างแน่นอน การเข้าถึง HTTP ผ่านเครือข่ายเซลลูลาร์มาพร้อมกับเวลาแฝงที่สูงขึ้นต่อคำขอ / การตอบสนอง ดังนั้นจึงมีบางกรณีที่การใช้การอัดภาพของคุณเป็นข้อมูลลงใน CSS หรือเทมเพลต HTML อาจเป็นประโยชน์ต่อแอปพลิเคชันเว็บมือถือ คุณควรวัดการใช้งานเป็นกรณี ๆ ไป - ฉันไม่สนับสนุนให้ใช้ข้อมูล URIs ทุกที่ในเว็บแอพมือถือ

โปรดทราบว่าเบราว์เซอร์มือถือมีข้อ จำกัด เกี่ยวกับขนาดไฟล์ทั้งหมดที่สามารถแคชได้ ขีด จำกัด สำหรับ iOS 3.2 ค่อนข้างต่ำ (25K ต่อไฟล์) แต่จะเพิ่มขึ้น (100K) สำหรับ Mobile Safari เวอร์ชันใหม่ ดังนั้นโปรดตรวจสอบขนาดไฟล์ทั้งหมดของคุณเมื่อรวมถึง URI ข้อมูล

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


23

หากคุณอ้างอิงภาพนั้นเพียงครั้งเดียวฉันไม่เห็นปัญหาในการฝังลงในไฟล์ CSS ของคุณ แต่เมื่อคุณใช้มากกว่าหนึ่งภาพหรือต้องการอ้างอิงหลาย ๆ ครั้งใน CSS ของคุณคุณอาจลองใช้แผนที่รูปภาพเดียวแทนคุณสามารถครอบตัดรูปภาพเดี่ยวของคุณจาก (ดูCSS Sprites )


16
หมายความว่าคุณควรมีคลาส css หนึ่งรายการบนองค์ประกอบสำหรับการอ้างอิงภาพพื้นหลังและคลาส css อื่นสำหรับการอ้างอิงออฟเซ็ตลงในรูปภาพนั้นเพื่อใช้สำหรับองค์ประกอบนั้น
Duncan Beevers

4
คุณควรมีคลาสไม่เกี่ยวกับองค์ประกอบที่อธิบายวิธีการนำเสนอเนื้อหา - คลาสเหล่านั้นควรมีชื่อและความหมาย (ซึ่งไม่สามารถทำได้เสมอไป แต่ดีสำหรับการถ่ายภาพ) หากองค์ประกอบหลายรายการใช้ภาพเดียวกันและคุณต้องการ เข้ารหัสภาพนั้นใน CSS เพียงแค่ปล่อยภาพออกจากการประกาศและใช้กฎ css ในภายหลังเพื่อประกาศและฝังภาพสำหรับตัวเลือก / คลาสหลายรายการ
Adam Tolley

1
หากคุณกำลังถ่ายภาพคลาสที่มีความหมายและต้องการข้อมูลภาพเพียงครั้งเดียวคุณสามารถมีสไตล์ที่แยกต่างหากซึ่งจะแสดงรายการตัวเลือกที่เกี่ยวข้องทั้งหมดจากนั้นจึงกำหนดออฟเซ็ตในรูปแบบตัวเลือกต่อตัวเลือก แน่นอนว่าสำหรับภาพที่มีขนาดเล็กมากในหลายสถานที่รายชื่อตัวเลือกอาจจะมีขนาดใหญ่กว่าข้อมูล ...
สิงห์

เพื่อหลีกเลี่ยงหลายคลาสและระบุเพียง sprite ชีตหนึ่งครั้งคุณสามารถใช้ตัวเลือกแอททริบิวต์:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

หนึ่งในสิ่งที่ฉันอยากจะแนะนำก็คือให้มีสไตล์ชีทแยกกันสองอัน: อันที่หนึ่งด้วยคำจำกัดความสไตล์ปกติของคุณและอีกอันหนึ่งที่มีรูปภาพของคุณในการเข้ารหัส base64

คุณต้องรวมสไตล์ชีทพื้นฐานไว้ก่อนสไตล์ชีทของภาพ

วิธีนี้คุณจะมั่นใจได้ว่าคุณกำลังดาวน์โหลดและนำสไตล์ชีททั่วไปมาใช้โดยเร็วที่สุดเท่าที่จะเป็นไปได้กับเอกสาร แต่ในขณะเดียวกันคุณก็จะได้รับผลกำไรจากคำขอ HTTP ที่ลดลงและผลประโยชน์อื่น ๆ


1
ฉันชอบสิ่งนี้ในทางทฤษฎี ทุกคนสามารถคิดถึงข้อโต้แย้งใด ๆ กับ?
Rob

ฉันแค่ Googling ตัวเองเพื่อดูว่ามันเป็นความคิดที่ดีและมาที่นี่หรือไม่ ในกรณีของฉันรูปภาพทั้งหมดเป็นเพียงสิ่ง UI และฉันคิดว่านี่จะเป็นความคิดที่ดี ไม่แน่ใจว่ามันดีกว่าการใช้ css sprites แต่ฉันรู้สึกว่ามันง่ายกว่าที่จะจัดการถ้าคุณทำการเปลี่ยนแปลงในอนาคต ชอบที่จะรู้ว่าถ้าใครมีอะไรกับเรื่องนี้
Craig

20

Base64 เพิ่มขนาดภาพประมาณ 10% หลังจาก GZipped แต่จะให้ประโยชน์มากกว่าเมื่อเทียบกับมือถือ เนื่องจากมีแนวโน้มโดยรวมกับการออกแบบเว็บที่ตอบสนองจึงขอแนะนำ

W3C ยังแนะนำวิธีการนี้สำหรับมือถือและถ้าคุณใช้ท่อส่งทรัพย์สินในรางนี่เป็นคุณสมบัติเริ่มต้นเมื่อบีบอัด css ของคุณ

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


จุดดีมือถือ / ตอบสนองแม้ว่าฉันไม่แน่ใจ 10% คุณจะได้รับข้อมูลจากที่ไหน
Dimitar Christoff

3
สิ่งนี้ถูกต้อง สิ่งที่ช้าที่สุดในอุปกรณ์มือถือคือการเปิด / ปิดการเชื่อมต่อ http แนะนำให้ย่อขนาดเล็กสุด
Rafael Sanches

แม้จะมีผลลัพธ์ w3 ในการทดสอบบางอย่างฉันทำขนาดของภาพเพิ่มขึ้น ~ 25% :(
Fabrizio Calderan

2
ฉันเดาว่ามันสามารถเพิ่มได้ถึง 33% ถ้ามันเป็นไปไม่ได้ที่จะซิปมัน
Léon Pelletier

1
บนมือถือ 10% ไม่มีอะไรเทียบได้กับการสร้างการเชื่อมต่อ http
Rafael Sanches

4

ฉันไม่เห็นด้วยกับคำแนะนำในการสร้างไฟล์ CSS แยกต่างหากสำหรับรูปภาพที่ไม่ใช่บรรณาธิการ

สมมติว่ารูปภาพมีวัตถุประสงค์เพื่อ UI มันเป็นสไตล์เลเยอร์การนำเสนอและตามที่กล่าวไว้ข้างต้นหากคุณกำลังทำ UI บนมือถือเป็นความคิดที่ดีที่จะเก็บสไตล์ทั้งหมดไว้ในไฟล์เดียวเพื่อให้สามารถแคชได้ครั้งเดียว


3

ในกรณีของฉันมันอนุญาตให้ฉันใช้สไตล์ชีท CSS โดยไม่ต้องกังวลกับการคัดลอกรูปภาพที่เกี่ยวข้องเนื่องจากมันถูกฝังอยู่ภายใน


3

ฉันพยายามสร้างแนวคิดออนไลน์ของเครื่องมือวิเคราะห์ CSS / HTML:

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

มันสามารถ:

  • ดาวน์โหลดและแยกวิเคราะห์ไฟล์ HTML / CSS แยกองค์ประกอบ href / src / url
  • ตรวจจับการบีบอัด (gzip) และข้อมูลขนาดบน URL
  • เปรียบเทียบขนาดข้อมูลต้นฉบับขนาดข้อมูล base64 และขนาดข้อมูล base64 gzipped
  • แปลง URL (รูปภาพ, ฟอนต์, css, ... ) ไปเป็นรูปแบบ URI data64
  • นับจำนวนคำขอที่สามารถงดเว้นได้โดย Data URIs

ความคิดเห็น / ข้อเสนอแนะยินดีต้อนรับ

แอน


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)

จากนั้นคุณสามารถคลิกขวาที่รูปภาพใน file explorer และ SendTo ไปยัง batchfile

Ok ขอ Admiinstartor และรอให้หน้าต่าง shell คำสั่ง black ปิด

จากนั้นเพียงแค่วางผลลัพธ์จากคลิปบอร์ดลงในตัวแก้ไขข้อความของคุณ ...

<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 ตามที่พวกเขาอยู่แล้วดีและบีบอัดหลังจากบีบอัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.