Việc nhúng dữ liệu hình ảnh nền vào CSS là Base64 tốt hay xấu?


475

Tôi đã xem xét nguồn gốc của một mô tả người dùng greasemonkey và nhận thấy những điều sau đây trong css của họ:

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

Tôi có thể đánh giá cao rằng một tập lệnh greasemonkey sẽ muốn gói bất cứ thứ gì nó có thể trong nguồn thay vì lưu trữ nó trên máy chủ, điều đó là quá rõ ràng. Nhưng vì tôi chưa thấy kỹ thuật này trước đây, tôi đã xem xét việc sử dụng nó và nó có vẻ hấp dẫn vì một số lý do:

  1. Nó sẽ giảm lượng yêu cầu HTTP khi tải trang, do đó nâng cao hiệu suất
  2. Nếu không có CDN, thì nó sẽ giảm lượng lưu lượng truy cập được tạo thông qua cookie được gửi cùng với hình ảnh
  3. Các tệp CSS có thể được lưu trữ
  4. Các tệp CSS có thể được GZIPPED

Xem xét rằng IE6 (ví dụ) có vấn đề với bộ đệm cho hình ảnh nền, có vẻ như đó không phải là ý tưởng tồi tệ nhất ...

Vì vậy, đây là một thực hành tốt hay xấu, tại sao bạn không sử dụng nó và bạn sẽ sử dụng công cụ nào để mã hóa hình ảnh?

cập nhật - kết quả kiểm tra

Đẹp, nhưng nó sẽ ít hữu ích hơn cho những hình ảnh nhỏ hơn, tôi đoán vậy.

CẬP NHẬT: Bryan McQuade, một kỹ sư phần mềm của Google, làm việc trên PageSpeed, bày tỏ tại ChromeDevSummit 2013 rằng dữ liệu: uris trong CSS được coi là một mô hình chống chặn kết xuất để cung cấp CSS quan trọng / tối thiểu trong suốt cuộc nói chuyện của anh ấy #perfmatters: Instant mobile web apps. Xem http://developer.chrome.com/devsummit/simes và ghi nhớ điều đó - slide thực tế


Làm một số bài kiểm tra chạy? Sẽ rất thú vị khi nén có thể bù cho thực tế bạn mã hóa 64.
Dykam

đã đăng kết quả của bài kiểm tra, cũng tận dụng trên blog của tôi Fragged.org/ Khăn
Dimitar Christoff

5
Câu hỏi hay. Chỉ muốn thêm rằng nó không hoạt động cho IE7 trở xuống. Nhưng có một số công việc xung quanh. Đây là một bài viết hay về nó jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
Thêm nhiều PRO:giới hạn bộ nhớ cache trên thiết bị di động ... CON:một số hình ảnh nên được coi là nội dung thay vì trình bày đơn giản và do đó phù hợp hơn với các thẻ HTML IMG so với hình nền CSS.
one.beat.consumer

1
@DimitarChristoff: Tôi là một fan hâm mộ của việc nhúng các biểu tượng nhỏ với base64 vì tính dễ dàng tương đối của nó (khi so sánh với việc phun mãnh liệt) và rất vui khi chấp nhận kích thước trên đầu. Cảm ơn vì đã chỉ ra rằng nó không phải luôn luôn như vậy (tức là đã giải nén base64 nhúng có thể tốt hơn cả về quy mô tài sản tuyệt đối cũng)
ov

Câu trả lời:


166

Đó không phải là một ý tưởng tốt khi bạn muốn hình ảnh và thông tin phong cách của bạn được lưu trữ riêng biệt. Ngoài ra, nếu bạn mã hóa một hình ảnh lớn hoặc một số lượng đáng kể hình ảnh vào tệp css của mình, trình duyệt sẽ mất nhiều thời gian hơn để tải xuống tệp rời khỏi trang web của bạn mà không có bất kỳ thông tin kiểu nào cho đến khi quá trình tải xuống hoàn tất. Đối với những hình ảnh nhỏ mà bạn không có ý định thay đổi thường xuyên nếu đó là một giải pháp tốt.

khi tạo mã hóa base64:


less có chức năng data-uri sẽ nội tuyến một hình ảnh lesscss.org/#reference
Luke Trang

đó là một ý tưởng tốt nếu bạn muốn có sự bảo vệ tối thiểu cho những hình ảnh đó để chúng không bị lưu vào bộ nhớ cache hoặc có thể được tải xuống bằng cách nhấp chuột phải -> lưu
vsync

"Đó không phải là một ý tưởng tốt khi bạn muốn hình ảnh và thông tin phong cách của bạn được lưu trữ riêng biệt" - không có gì ngăn bạn có tất cả các hình ảnh trong một tệp .css riêng biệt.
magritte

Thực hành và kiểm tra của tôi không xác nhận tuyên bố của bạn. Lấy làm tiếc.
TomeeNS

55

Câu trả lời này đã hết hạn và không nên sử dụng.

1) Độ trễ trung bình nhanh hơn nhiều trên thiết bị di động trong năm 2017. https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network

2) Ghép kênh HTTP2 https://http2.github.io/faq/#why-is-http2-multiplexed

"URI dữ liệu" chắc chắn nên được xem xét cho các trang web di động. Truy cập HTTP qua các mạng di động đi kèm với độ trễ cao hơn cho mỗi yêu cầu / phản hồi. Vì vậy, có một số trường hợp sử dụng trong đó gây nhiễu hình ảnh của bạn dưới dạng dữ liệu vào các mẫu CSS hoặc HTML có thể có lợi trên các ứng dụng web di động. Bạn nên đo lường mức độ sử dụng trong từng trường hợp cụ thể - Tôi không ủng hộ rằng URI dữ liệu nên được sử dụng ở mọi nơi trong ứng dụng web trên thiết bị di động.

Lưu ý rằng trình duyệt di động có giới hạn về tổng kích thước tệp có thể được lưu trong bộ nhớ cache. Giới hạn cho iOS 3.2 khá thấp (25K mỗi tệp), nhưng ngày càng lớn hơn (100K) cho các phiên bản Mobile Safari mới hơn. Vì vậy, hãy chắc chắn để theo dõi tổng kích thước tệp của bạn khi bao gồm các URI dữ liệu.

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


23

Nếu bạn tham chiếu hình ảnh đó chỉ một lần, tôi không thấy vấn đề gì khi nhúng nó vào tệp CSS của bạn. Nhưng một khi bạn sử dụng nhiều hơn một hình ảnh hoặc cần tham chiếu nó nhiều lần trong CSS của mình, bạn có thể cân nhắc sử dụng một bản đồ hình ảnh duy nhất thay vào đó bạn có thể cắt các hình ảnh duy nhất của mình từ (xem CSS Sprites ).


16
Điều đó chỉ có nghĩa là bạn nên có một lớp css trên một phần tử để tham chiếu hình nền và một lớp css khác để tham chiếu các offset vào hình ảnh đó để sử dụng cho phần tử đó.
Duncan Beevers

4
bạn không nên có các lớp về các yếu tố mô tả cách trình bày tài liệu - các lớp đó phải được đặt tên tốt và ngữ nghĩa (điều này không phải lúc nào cũng có thể, nhưng tốt để chụp) Nếu nhiều yếu tố sử dụng cùng một hình ảnh, và bạn muốn mã hóa hình ảnh đó trong CSS, chỉ cần để hình ảnh ra khỏi các khai báo và sử dụng quy tắc css sau để khai báo và nhúng hình ảnh cho nhiều bộ chọn / lớp.
Adam Tolley

1
Nếu bạn đang chụp cho các lớp ngữ nghĩa và cũng chỉ muốn dữ liệu hình ảnh một lần, bạn có thể có một kiểu riêng liệt kê tất cả các bộ chọn có liên quan, sau đó bù lại được xác định theo kiểu mỗi bộ chọn. Tất nhiên, đối với một hình ảnh rất nhỏ ở nhiều nơi, danh sách bộ chọn có thể lớn hơn dữ liệu ...
Leo

Để tránh nhiều lớp và chỉ chỉ định một bảng sprite một lần, bạn có thể sử dụng bộ chọn thuộc tính:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

Một trong những điều tôi muốn đề xuất là có hai biểu định kiểu riêng biệt: Một với định nghĩa kiểu thông thường của bạn và một kiểu khác chứa hình ảnh của bạn trong mã hóa base64.

Bạn phải bao gồm biểu định kiểu cơ sở trước khi biểu định kiểu ảnh tất nhiên.

Bằng cách này, bạn sẽ đảm bảo rằng biểu định kiểu thông thường của bạn được tải xuống và áp dụng càng sớm càng tốt cho tài liệu, nhưng đồng thời bạn cũng thu được lợi nhuận từ các yêu cầu http giảm và các lợi ích dữ liệu khác mà bạn cung cấp cho bạn.


1
Tôi thích điều này trong lý thuyết. Bất cứ ai có thể nghĩ về bất kỳ đối số chống lại?
Rob

Tôi chỉ tự mình làm điều này để tìm hiểu xem đó có phải là một ý tưởng tốt và đã đến đây. Trong trường hợp của tôi, tất cả các hình ảnh chỉ là công cụ UI và tôi đã nghĩ rằng đây sẽ là một ý tưởng tốt. Không chắc chắn nếu nó tốt hơn so với việc sử dụng các sprite css nhưng tôi cảm thấy việc quản lý sẽ dễ dàng hơn nếu bạn thực hiện các thay đổi trong tương lai. Rất muốn biết nếu có ai chống lại điều này?
Craig

20

Base64 thêm khoảng 10% vào kích thước hình ảnh sau GZipped nhưng điều đó vượt xa lợi ích khi nói đến di động. Vì có một xu hướng chung với thiết kế web đáp ứng, nó rất được khuyến khích.

W3C cũng đề xuất phương pháp này cho thiết bị di động và nếu bạn sử dụng đường dẫn tài sản trong đường ray, đây là một tính năng mặc định khi nén css của bạn

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


điểm tốt là di động / phản hồi mặc dù tôi không chắc chắn 10%, bạn lấy dữ liệu đó từ đâu?
Dimitar Christoff

3
Chính xác. Điều chậm nhất trong mọi thiết bị di động là mở / đóng các kết nối http. Giảm thiểu chúng được khuyến khích.
Rafael Sanches

mặc dù kết quả w3, trong một số thử nghiệm, tôi đã làm kích thước hình ảnh tăng ~ 25% :(
Fabrizio Calderan

2
Tôi đoán nó có thể tăng tới 33% nếu không thể nén nó.
Léon Pelletier

1
trên di động 10% không là gì so với việc tạo kết nối http
Rafael Sanches

4

Tôi không đồng ý với đề xuất tạo các tệp CSS riêng cho các hình ảnh không biên tập.

Giả sử hình ảnh là dành cho mục đích UI, đó là kiểu dáng lớp trình bày và như đã đề cập ở trên, nếu bạn đang sử dụng UI trên thiết bị di động, chắc chắn nên giữ tất cả kiểu dáng trong một tệp để có thể lưu vào bộ nhớ cache một lần.


3

Trong trường hợp của tôi, nó cho phép tôi áp dụng biểu định kiểu CSS mà không phải lo lắng về việc sao chép các hình ảnh liên quan, vì chúng đã được nhúng bên trong.


3

Tôi đã cố gắng tạo một khái niệm trực tuyến về công cụ phân tích CSS / HTML:

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

Nó có thể:

  • Tải xuống và phân tích các tệp HTML / CSS, trích xuất các phần tử href / src / url
  • Phát hiện nén (gzip) và kích thước dữ liệu trên URL
  • So sánh kích thước dữ liệu gốc, kích thước dữ liệu base64 và kích thước dữ liệu cơ sở được nén
  • Chuyển đổi URL (hình ảnh, phông chữ, css, ...) sang sơ đồ URI dữ liệu cơ sở64.
  • Đếm số lượng yêu cầu có thể được tha bởi URI dữ liệu

Bình luận / đề xuất đều được chào đón.

Antonin


3

Bạn có thể mã hóa nó trong 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);
?>

Nguồn



0

Cảm ơn thông tin ở đây. Tôi thấy việc nhúng này hữu ích và đặc biệt cho thiết bị di động, đặc biệt là với tệp css của hình ảnh được nhúng vào bộ nhớ cache.

Để giúp cuộc sống dễ dàng hơn, vì (các) trình chỉnh sửa tệp của tôi không xử lý việc này, tôi đã tạo một vài tập lệnh đơn giản cho công việc chỉnh sửa máy tính xách tay / máy tính để bàn, chia sẻ ở đây trong trường hợp chúng được sử dụng cho bất kỳ ai khác. Tôi đã bị mắc kẹt với php vì nó đang xử lý những điều này trực tiếp và rất tốt.

Trong Windows 8.1, hãy nói ---

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

... với tư cách Quản trị viên, bạn có thể thiết lập lối tắt đến tệp bó trong đường dẫn của mình. Tập tin bó đó sẽ gọi một tập lệnh php (cli).

Sau đó, bạn có thể nhấp chuột phải vào một hình ảnh trong trình duyệt tệp và SendTo the batchfile.

Ok yêu cầu Admiinstartor và đợi cửa sổ shell lệnh đen đóng lại.

Sau đó, chỉ cần dán kết quả từ bảng ghi tạm vào trình soạn thảo văn bản của bạn ...

<img src="|">

hoặc là

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

Sau đây nên thích ứng cho hệ điều hành khác.

Tập tin hàng loạt ...

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

Và với php.exe trong đường dẫn của bạn, điều đó gọi một tập lệnh 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

Theo như tôi đã nghiên cứu,

Sử dụng: 1. Khi bạn đang sử dụng một sprite svg. 2. Khi hình ảnh của bạn có kích thước nhỏ hơn (tối đa 200mb).

Không sử dụng: 1. Khi bạn là hình ảnh lớn hơn. 2. Các biểu tượng như của Svg. Vì chúng đã tốt và được nén sau khi nén.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.