作为Base64,将背景图像数据嵌入CSS是好做法还是坏做法?


475

我一直在查看油脂猴子用户脚本的来源,并在他们的CSS中注意到以下内容:

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

我可以理解,滑脂脚本希望将其可以捆绑的所有内容捆绑在源代码中,而不是将其托管在服务器上,这很明显。但是由于我以前没有看过这种技术,因此我考虑了它的使用,并且由于许多原因,它似乎很有吸引力:

  1. 它将减少页面加载时的HTTP请求数量,从而提高性能
  2. 如果没有CDN,则它将减少通过Cookie与图像一起发送而产生的流量
  3. 可以缓存CSS文件
  4. CSS文件可以GZIPPED

考虑到IE6(例如)在背景图片缓存方面存在问题,这似乎不是最糟糕的主意...

那么,这是好事还是坏事,为什么您不使用它,以及使用哪种工具对图像进行base64编码?

更新-测试结果

  • 图片测试:http//fragged.org/dev/map-shot.jpg-133.6Kb

  • 测试网址:http : //fragged.org/dev/base64.html

  • 专用CSS文件: http//fragged.org/dev/base64.css-178.1Kb

  • GZIP编码服务器端

  • 发送给客户端的结果大小(YSLOW组件测试):59.3Kb

  • 发送到客户端浏览器的数据保存:74.3Kb

不错,但是我猜它对较小的图像用处不大。

更新:Google软件工程师Bryan McQuade在PageSpeed上表示,他在ChromeDevSummit 2013上表示,CSS中的data:uris被认为是在演讲期间提供关键/最小CSS的渲染阻止反模式#perfmatters: Instant mobile web apps。请参阅http://developer.chrome.com/devsum​​mit/sessions,并牢记这一点- 实际幻灯片


做一些测试吗?有趣的是,压缩可以补偿您对base64进行编码的事实。
Dykam

发布了测试结果,也可以在我的博客上使用fragged.org/…–
Dimitar Christoff

5
好问题。只是想补充一点,它不适用于IE7及以下版本。但是有一些解决方法。这是一篇很好的文章jonraasch.com/blog/css-data-uris-in-all-browsers
MartinF

2
PRO:在蜂窝设备上增加了更多缓存限制... CON:一些图像应被视为内容而不是简单的呈现,因此比CSS背景图像更适合HTML IMG标签。
one.beat.consumer 2012年

1
@DimitarChristoff:我一直喜欢在base64上嵌入小图标,因为它相对容易(与激进的拼写比较时),并且很高兴接受它的大小开销。感谢您指出并非总是如此(即,就绝对资产规模而言,gzip压缩的base64嵌入可能也更好)
2012年

Answers:


166

如果要分别缓存图像和样式信息,这不是一个好主意。同样,如果您在css文件中编码大图像或大量图像,则浏览器将花费更长的时间下载该文件,直到没有下载任何样式信息,您的网站才完成下载。对于小型图像,您不打算经常更改,这是一个很好的解决方案。

就生成base64编码而言:


less具有data-uri函数,它将内嵌图像lesscss.org/#reference
路加福音

如果您想对这些图像进行最小程度的保护,那么最好不要对它们进行缓存或通过右键单击->保存进行下载
-vsync

“当您希望分别缓存图像和样式信息时,这不是一个好主意”-没有什么能阻止您将所有图像保存在单独的.css文件中。
magritte 2014年

我的实践和测试无法确认您的陈述。抱歉。
TomeeNS '17

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

绝对应该为移动网站考虑“数据URI”。蜂窝网络上的HTTP访问每请求/响应具有更高的延迟。因此,在某些用例中,将图像作为数据阻塞到CSS或HTML模板中可能对移动Web应用程序有利。您应该根据具体情况评估使用情况-我并不主张在移动Web应用程序中的任何地方都应使用数据URI。

请注意,移动浏览器对可缓存文件的总大小有限制。iOS 3.2的限制非常低(每个文件25K),但对于较新版本的Mobile Safari的限制却越来越大(100K)。因此,在包含数据URI时,请务必注意文件的总大小。

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


23

如果您仅引用该图像一次,那么将其嵌入到CSS文件中就不会出现问题。但是一旦使用了多个图像或需要在CSS中多次引用它,您可能会考虑使用一个图像映射,而不是您可以从中裁剪单个图像(请参阅CSS Sprites)。


16
这仅意味着您应该在元素上有一个css类来引用背景图像,并在另一个css类上引用该图像中要用于该元素的偏移量。
邓肯·比弗斯

4
您不应在描述材料呈现方式的元素上使用任何类-这些类应具有良好的名称和语义(这并不总是可能的,但是很适合拍摄)如果多个元素使用相同的图像,并且您想在CSS中对该图像进行编码,将图像保留在声明之外,然后使用更高的CSS规则声明并嵌入多个选择器/类的图像。
亚当·托利

1
如果您要拍摄语义类并且还只需要图像数据一次,则可以使用单独的样式,该样式列出所有相关的选择器,然后列出按每个选择器样式定义的偏移量。当然,对于很多地方的非常小的图像,选择器列表可能比数据更大...
Leo

为了避免多个类并且仅指定一次Sprite工作表,可以使用属性选择器:[emoji] {background-image: url(data:image/png;base64,qwedfcsfrtgyu/=);} [emoji=happy] {background-position: -20px 0px;}
Chinoto Vokro

21

我建议的一件事是有两个单独的样式表:一个带有常规样式定义,另一个带有以base64编码形式包含图像的样式表。

当然,您必须在图像样式表之前包括基本样式表。

这样,您将确保下载常规样式表并尽快将其应用于文档,但与此同时,您将从减少的http请求和data-uris给您的其他好处中受益。


1
我在理论上喜欢这个。有人能想到反对吗?
罗布

我本人只是在谷歌上搜索,以了解这是否是个好主意,于是来到了这里。就我而言,图像全都是UI东西,我当时认为这是个好主意。不知道它是否比使用CSS精灵更好,但是我觉得如果将来进行更改,管理起来会更容易。想知道是否有人对此有任何反对吗?
Craig

20

G64压缩后,Base64将图像大小增加了约10%,但超过了移动应用带来的好处。由于响应式网页设计存在总体趋势,因此强烈建议您这样做。

W3C还建议将此方法用于移动设备,并且如果您在导轨中使用资产管道,则这是压缩CSS时的默认功能

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


虽然我不确定这10%是什么,但是您可以从哪里获得数据呢?
Dimitar Christoff

3
这是对的。在任何移动设备中最慢的事情是http连接的打开/关闭。建议最小化它们。
拉斐尔·桑切斯2012年

尽管有w3结果,但在某些测试中,我的确使图像大小增加了约25%:(
Fabrizio Calderan 2012年

2
我想如果根本无法压缩,它最多可以提高33%。
莱昂佩尔蒂埃

1
与创建http连接相比,移动设备上10%的内容毫无意义
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元素
  • 检测URL上的压缩(gzip)和大小数据
  • 比较原始数据大小,base64数据大小和压缩的base64数据大小
  • 将URL(图像,字体,css等)转换为base64数据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);
?>

资源



0

感谢您在此提供的信息。我发现这种嵌入很有用,尤其是对于移动设备而言,尤其是在嵌入图像的css文件被缓存的情况下。

为了使生活更轻松,因为我的文件编辑器本身无法解决这个问题,所以我为笔记本电脑/台式机编辑工作制作了一些简单的脚本,请在此处共享,以防其他用途。我一直坚持使用php,因为它可以直接很好地处理这些事情。

在Windows 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。由于它们已经很好并且在压缩后会压缩。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.