将背景图像数据作为 Base64 嵌入到 CSS 中是好还是坏做法?
-
13-09-2019 - |
题
我正在查看greasemonkey用户脚本的来源,并注意到他们的CSS中有以下内容:
.even { background: #fff url(data:image/gif;base64,R0lGODlhBgASALMAAOfn5+rq6uvr6+zs7O7u7vHx8fPz8/b29vj4+P39/f///wAAAAAAAAAAAAAAAAAAACwAAAAABgASAAAIMAAVCBxIsKDBgwgTDkzAsKGAhxARSJx4oKJFAxgzFtjIkYDHjwNCigxAsiSAkygDAgA7) repeat-x bottom}
我可以理解,greasemonkey 脚本希望将其可以包含的任何内容捆绑在源代码中,而不是将其托管在服务器上,这是显而易见的。但由于我以前没有见过这种技术,所以我考虑了它的用途,并且由于多种原因它似乎很有吸引力:
- 它将减少页面加载时的 HTTP 请求量,从而提高性能
- 如果没有 CDN,那么它将减少通过与图像一起发送的 cookie 产生的流量
- CSS 文件可以被缓存
- CSS 文件可以被压缩
考虑到 IE6(例如)在背景图像缓存方面存在问题,这似乎不是最糟糕的主意......
那么,这是一个好还是坏的做法,为什么您不使用它以及您将使用什么工具来对图像进行 Base64 编码?
更新-测试结果
用图像测试: http://fragged.org/dev/map-shot.jpg - 133.6KB
专用 CSS 文件:http://fragged.org/dev/base64.css - 178.1Kb
GZIP编码服务器端
最终发送给客户端的大小(yslow组件测试): 59.3KB
保存发送到客户端浏览器的数据: 74.3KB
不错,但我想,对于较小的图像来说,它的用处会稍微小一些。
更新:负责 PageSpeed 的 Google 软件工程师 Bryan McQuade 在 2013 年 ChromeDevSummit 演讲中表示,CSS 中的 data:uris 被认为是一种渲染阻塞反模式,用于提供关键/最小 CSS
#perfmatters: Instant mobile web apps
. 。看 http://developer.chrome.com/devsummit/sessions 并记住这一点 - 实际幻灯片
解决方案
当您希望单独缓存图像和样式信息时,这不是一个好主意。此外,如果您将大图像或大量图像编码到 css 文件中,则浏览器将需要更长的时间来下载文件,从而使您的网站没有任何样式信息,直到下载完成。对于您不打算经常更改(如果有的话)的小图像,这是一个很好的解决方案。
至于生成 Base64 编码:
其他提示
该答案已过时,不应使用。
1) 2017 年移动设备上的平均延迟要快得多。 https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network
2)HTTP2复用https://http2.github.io/faq/#why-is-http2-多路复用
移动网站绝对应该考虑“数据 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/
如果您只引用该图像一次,我认为将其嵌入到您的 CSS 文件中不会有问题。但是,一旦您使用多个图像或需要在 CSS 中多次引用它,您可能会考虑使用单个图像映射,然后您可以从中裁剪单个图像(请参阅 CSS 精灵).
我建议的一件事是有两个单独的样式表:一种包含常规样式定义,另一种包含采用 Base64 编码的图像。
当然,您必须在图像样式表之前包含基本样式表。
这样,您将确保尽快下载常规样式表并将其应用到文档,同时您还可以从减少的 http 请求和 data-uris 为您带来的其他好处中获益。
GZipped 后,Base64 使图像大小增加了约 10%,但这超过了移动设备所带来的好处。由于响应式网页设计已成为总体趋势,因此强烈推荐。
W3C 还建议在移动设备上使用这种方法,如果您在 Rails 中使用资产管道,那么这是压缩 css 时的默认功能
我不同意为非编辑图像创建单独的 CSS 文件的建议。
假设图像用于 UI 目的,它是表示层样式,如上所述,如果您正在做移动 UI,那么将所有样式保留在单个文件中绝对是一个好主意,这样就可以缓存一次。
就我而言,它允许我应用 CSS 样式表,而不必担心复制关联的图像,因为它们已经嵌入其中。
我尝试创建一个 CSS/HTML 分析工具的在线概念:
http://www.motobit.com/util/base64/css-images-to-base64.asp
它可以:
- 下载并解析HTML/CSS文件,提取href/src/url元素
- 检测 URL 上的压缩 (gzip) 和大小数据
- 比较原始数据大小、base64 数据大小和 gzipped base64 数据大小
- 将 URL(图像、字体、CSS...)转换为 Base64 数据 URI 方案。
- 计算数据 URI 可以节省的请求数量
欢迎提出意见/建议。
安东尼
您可以用 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);
?>
为 Sublime Text 2 的用户带来一些好处,有一个插件可以提供我们在 ST 中加载图像的 Base64 代码。
称为 Image2base64: https://github.com/tm-minty/sublime-text-2-image2base64
附:切勿保存插件生成的此文件,因为它会覆盖该文件并会破坏。
感谢您提供的信息。我发现这种嵌入很有用,特别是对于移动设备,尤其是在嵌入图像的 css 文件被缓存的情况下。
为了让生活更轻松,由于我的文件编辑器本身无法处理此问题,我为笔记本电脑/台式机编辑工作制作了几个简单的脚本,在此处共享,以防它们对其他人有任何用处。我一直坚持使用 php,因为它可以直接且很好地处理这些事情。
在 Windows 8.1 下说——
C:\Users\`your user name`\AppData\Roaming\Microsoft\Windows\SendTo
...作为管理员,您可以在路径中建立批处理文件的快捷方式。该批处理文件将调用 php (cli) 脚本。
然后,您可以右键单击文件资源管理器中的图像,然后发送到批处理文件。
Ok Admiinstartor 请求,然后等待黑色命令 shell 窗口关闭。
然后只需将剪贴板中的结果粘贴到文本编辑器中......
<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));
?>
据我研究,
使用 :1.当您使用 svg 精灵时。2.当您的图像较小时(最大 200mb)。
不要使用:1.当你的图像更大时。2.图标为 svg。因为它们已经很好并在压缩后进行了 gzip 压缩。