ฉันควรฝังรูปภาพเป็น data / base64 ใน CSS หรือ HTML


131

เพื่อลดจำนวนคำขอบนเซิร์ฟเวอร์ฉันได้ฝังรูปภาพ (PNG & SVG) เป็น BASE64 ลงใน css โดยตรง (อัตโนมัติในกระบวนการสร้าง)

แบบนี้:

background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFWHRTb2Z0d2FyZQBBZG etc...);

นี่เป็นแนวทางปฏิบัติที่ดีหรือไม่? มีเหตุผลบางประการที่ควรหลีกเลี่ยงสิ่งนี้หรือไม่? มีเบราว์เซอร์หลักบางตัวที่ไม่รองรับ data url หรือไม่?

คำถามโบนัส: การทำเช่นนี้กับ CSS & JS ยังสมเหตุสมผลหรือไม่


1
มีคนจำนวนไม่น้อยที่ใช้ IE7 อีกต่อไปและสำหรับข้อเสียทั้งหมดมีข้อดีคือมีไฟล์ภาพให้จัดการน้อยลง! เช่นถ้าคุณต้องการวาดเส้นพิเศษสำหรับส่วนประกอบของต้นไม้จากนั้นการฝังภาพข้อศอกเล็ก ๆ ใน css ร่วมกับ repeat-x หรือ repeat-y จะขจัดความจำเป็นในการตรวจสอบให้แน่ใจว่าไฟล์ภาพพิเศษอยู่ในตำแหน่งที่ถูกต้อง (มีน้อยมาก ค่าใช้จ่ายสำหรับกรณีการใช้งานนี้)
DaveAlger

คำตอบ:


153

นี่เป็นแนวทางปฏิบัติที่ดีหรือไม่? มีเหตุผลบางประการที่ควรหลีกเลี่ยงสิ่งนี้หรือไม่?

โดยปกติแล้วเป็นแนวทางปฏิบัติที่ดีสำหรับอิมเมจ CSS ขนาดเล็กมากที่จะใช้ร่วมกันเท่านั้น (เช่น CSS สไปรต์) เมื่อความเข้ากันได้ของ IE ไม่สำคัญและการบันทึกคำขอนั้นสำคัญกว่าความสามารถในการแคช

มีข้อเสียที่น่าสังเกตหลายประการ:

  • ไม่ทำงานเลยใน IE6 และ 7

  • ใช้งานได้กับทรัพยากรที่มีขนาดไม่เกิน 32k ใน IE8เท่านั้น นี่คือขีด จำกัด ที่ใช้หลังจากการเข้ารหัส base64 กล่าวอีกนัยหนึ่งความยาวไม่เกิน 32768 อักขระ

  • มันบันทึกคำขอ แต่ขยายหน้า HTML แทน! และทำให้ภาพไม่สามารถแคชได้ พวกเขาจะโหลดทุกครั้งที่โหลดเพจที่มีหรือสไตล์ชีต

  • การเข้ารหัส Base64 ขยายขนาดภาพ 33%

  • หากให้บริการในแหล่งข้อมูล gzipped data:รูปภาพแทบจะเป็นปัญหาอย่างมากกับทรัพยากรของเซิร์ฟเวอร์! โดยปกติแล้วภาพจะใช้ CPU อย่างเข้มข้นในการบีบอัดโดยลดขนาดลงเพียงเล็กน้อย


2
@meo ประเด็นที่น่าสนใจ. ฉันคาดว่าสิ่งนี้จะไม่ดีต่อประสิทธิภาพของ gzip เนื่องจากโดยปกติแล้วรูปภาพจะถูกบีบอัดอย่างเหมาะสมที่สุดอยู่แล้ว การบีบอัดข้อมูลเหล่านี้ทำให้เสียพื้นที่ CPU จำนวนมากสำหรับการเพิ่มเปอร์เซ็นต์ตัวเลขหลักเดียว ลองบีบอัดไฟล์ JPG แล้วคุณจะเห็นความหมาย ฉันจะแก้ไขเป็นคำตอบ
Pekka

1
ฉันรู้ว่าการบีบอัดรูปภาพที่บีบอัดไม่ใช่วิธีที่จะไป แต่ฉันคิดว่ามันอาจจะมีประสิทธิภาพมากกว่าบนฐาน 64 โดยเฉพาะอย่างยิ่งเมื่อคุณมีภาพมากกว่าหนึ่งภาพในแหล่งที่มา
แม้ว

2
@meo ไม่มันจะไม่มีประสิทธิภาพมากขึ้นบน base64 ภายใต้สถานการณ์ใด ๆ เนื่องจากรูปแบบพื้นฐานจะยังคงเป็นข้อมูลภาพที่ถูกบีบอัดซึ่งเพิ่งเกิดขึ้นเพื่อแสดงในสัญกรณ์ base64
Pekka

1
@meo อ่าฉันเห็น ซึ่งจะใช้ไม่ได้ใน IE เลยและมีปัญหาในการแคชเหมือนกัน: คุณบันทึกคำขอ แต่คำขอทุกหน้าจะมีขนาดใหญ่ขึ้น โดยปกติแล้วมันอาจจะดีกว่ามากถ้าจะรวมทุกอย่างไว้ใน CSS เดียวและไฟล์ JS หนึ่งไฟล์
Pekka

5
จะไม่ขยายหน้า HTML เมื่อคุณฝังรูปภาพในไฟล์ CSS ตามที่คำถามระบุ
Daniel Beardsley

38

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

เป็นไปไม่ได้เลย (และค่อนข้างง่ายจริงๆ) ในการออกแบบกระบวนการง่ายๆที่จะเดินผ่านรูปภาพโฟลเดอร์และจะสร้าง CSS เดียวพร้อมรูปภาพทั้งหมดของโฟลเดอร์นี้

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

แน่นอนว่ามันแฮ็ค ไม่ต้องสงสัยเลย. เหมือนกับสไปรท์คือแฮ็ค ในโลกที่สมบูรณ์แบบนี้จะไม่จำเป็นจนกว่าจะถึงตอนนั้นวิธีปฏิบัติที่เป็นไปได้หากสิ่งที่คุณต้องแก้ไขคือ

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

มุมมองของฉัน.


4
สิ่งนี้ควรได้รับการโหวตเพื่อให้ได้รับความสนใจมากขึ้น คำตอบอื่น ๆ ค่อนข้างล้าสมัย - พวกเขาพูดถึง IE6 ในขณะที่ IE8 นั้นล้าสมัยไปแล้วในทุกวันนี้ ... (และขอบคุณสำหรับสิ่งนั้น)
Hertzel Guinness

11

ไม่ใช่วิธีปฏิบัติที่ดี เบราว์เซอร์บางตัวไม่รองรับ URI ข้อมูล (เช่น IE 6 และ 7) หรือการรองรับมี จำกัด (เช่น 32KB สำหรับ IE8)

ดูบทความ Wikipedia นี้เพื่อดูรายละเอียดทั้งหมดเกี่ยวกับข้อเสีย URI ของข้อมูล:

ข้อเสีย

  • URI ข้อมูลจะไม่ถูกแคชแยกต่างหากจากเอกสารที่มีอยู่ (เช่นไฟล์ CSS หรือ HTML) ดังนั้นข้อมูลจะถูกดาวน์โหลดทุกครั้งที่มีการดาวน์โหลดเอกสารที่มีอีกครั้ง
  • เนื้อหาจะต้องเข้ารหัสใหม่และฝังใหม่ทุกครั้งที่มีการเปลี่ยนแปลง
  • Internet Explorer ถึงเวอร์ชัน 7 (ประมาณ 15% ของตลาด ณ เดือนมกราคม 2554) ขาดการสนับสนุน
  • Internet Explorer 8 จำกัด URI ของข้อมูลไว้ที่ความยาวสูงสุด 32 KB
  • ข้อมูลจะรวมเป็นสตรีมอย่างง่ายและสภาพแวดล้อมการประมวลผลหลายอย่าง (เช่นเว็บเบราว์เซอร์) อาจไม่รองรับการใช้คอนเทนเนอร์ (เช่นmultipart/alternativeหรือmessage/rfc822) เพื่อให้มีความซับซ้อนมากขึ้นเช่นข้อมูลเมตาการบีบอัดข้อมูลหรือการต่อรองเนื้อหา
  • URI ของข้อมูลที่เข้ารหัส Base64 มีขนาดใหญ่กว่าไบนารีเทียบเท่า 1/3 (อย่างไรก็ตามค่าใช้จ่ายนี้จะลดลงเหลือ 2-3% หากเซิร์ฟเวอร์ HTTP บีบอัดการตอบสนองโดยใช้ gzip)
  • URI ของข้อมูลทำให้ซอฟต์แวร์รักษาความปลอดภัยกรองเนื้อหาได้ยากขึ้น

3
มีการดาวน์โหลด CSS ซ้ำตามคำขอทุกครั้งหรือไม่ นั่นคือสิ่งใหม่! นอกจากนี้หากคุณเคยเก็บไฟล์มาก่อนในชีวิตคุณจะสังเกตเห็นว่าอัตราการบีบอัดไม่ใช่ 2-3%! ถ้าฉันจำไม่ผิดฉันเคยเห็นเทคนิคนี้เป็นครั้งแรกใน yahoo.com ... เห็นได้ชัดว่าไม่ใช่การปฏิบัติที่ดี!
StefanNch

@StefanNch นั่นไม่ใช่สิ่งที่พูด ในข้อความที่ตัดตอนมา "มีเอกสาร" หมายถึงไฟล์ css
Christophe

9

ฉันใช้ data-uri เป็นเวลาประมาณหนึ่งเดือนและฉันเพิ่งหยุดใช้เพราะมันทำให้สไตล์ชีตของฉันมีขนาดใหญ่มาก

Data-uri ทำงานใน IE6 / 7 (คุณเพียงแค่ต้องให้บริการไฟล์mhtmlไปยังเบราว์เซอร์เหล่านั้น)

ประโยชน์อย่างหนึ่งที่ฉันได้รับจากการใช้ data-uri คือภาพพื้นหลังของฉันจะแสดงผลทันทีที่ดาวน์โหลดสไตล์ชีตซึ่งต่างจากการโหลดทีละน้อยที่เราเห็นเป็นอย่างอื่น

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


3

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


ฉันมีสไปรต์อยู่แล้วฉันสงสัยว่าฉันสามารถปรับให้เหมาะสมยิ่งขึ้นด้วยวิธีนั้นได้หรือไม่
แม้ว

2

ฉันไม่รู้เกี่ยวกับแนวทางปฏิบัติทั่วไปที่ดีที่สุด แต่ฉันไม่อยากเห็นเรื่องแบบนั้นถ้าฉันสามารถช่วยได้ :)

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

มีสาเหตุที่คุณคิดว่ามีคำขอไปยังเซิร์ฟเวอร์มากเกินไปในขณะนี้หรือไม่?


4
ทำให้จำนวนคำขอเป็นหนึ่งในความนิยมที่ยิ่งใหญ่ที่สุดหากคุณสนใจเกี่ยวกับความสมบูรณ์แบบสิ่งแรกที่ต้องพยายามแก้ไข โปรดดูที่ yahoo ใช้developer.yahoo.com/performance/rules.html "การลดจำนวนคอมโพเนนต์จะช่วยลดจำนวนคำขอ HTTP ที่ต้องใช้ในการแสดงผลเพจซึ่งเป็นกุญแจสำคัญในการทำให้เพจเร็วขึ้น"
MemeDeveloper

0

ฉันขอแนะนำสำหรับรูปภาพขนาดเล็กที่ใช้บ่อยเช่นไอคอนทั่วไปของเว็บแอปพลิเคชัน

  • เล็ก ๆ เนื่องจากการเข้ารหัส Base64 จะเพิ่มขนาด
  • มักใช้เนื่องจากสิ่งนี้แสดงให้เห็นถึงเวลาในการโหลดครั้งแรกที่นานขึ้น

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

ข้อมูลเพิ่มเติมรวบรวมไว้ที่นี่: http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/

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