将背景图像数据嵌入到CSS中作为Base64的好或坏做法?

Is embedding background image data into CSS as Base64 good or bad practice?

我正在查看GreaseMonkey用户脚本的源代码,并注意到它们的CSS中有以下内容:

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

我很感激GreaseMonkey脚本希望将它可以在源代码中捆绑的任何东西,而不是将其托管在服务器上,这已经足够明显了。但是,由于我以前没有见过这种技术,我考虑过它的使用,它似乎有很多原因:

  • 它将减少页面加载时的HTTP请求量,从而提高性能
  • 如果没有cdn,那么它将减少通过cookie生成的流量,这些cookie与图像一起发送。
  • 可以缓存CSS文件
  • CSS文件可以gzip
  • 考虑到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-1781kb

    • gzip编码服务器端

    • 发送到客户端的结果大小(yslow部件测试):59.3kb

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

    很好,但我想它对较小的图像会稍微不太有用。

    UPDATE: Bryan McQuade, a software engineer at Google, working on PageSpeed, expressed at ChromeDevSummit 2013 that data:uris in CSS is considered a render-blocking anti-pattern for delivering critical/minimal CSS during his talk #perfmatters: Instant mobile web apps. See http://developer.chrome.com/devsummit/sessions and keep that in mind - actual slide


    当您希望单独缓存图像和样式信息时,这不是一个好主意。另外,如果您将一个大图像或大量图像编码到您的CSS文件中,则在下载完成之前,浏览器将花费更长的时间来下载离开您的站点且没有任何样式信息的文件。对于那些你不想经常改变的小图像来说,这是一个很好的解决方案。

    至于生成base64编码:

    • HTTP://B64.IO/
    • http://www.motobit.com/util/base64-decoder-encoder.asp(上传)
    • http://www.greyvern.com/code/php/binary2base64(来自下面的小教程链接)


    此答案已过时,不应使用。

    1)2017年,手机的平均延迟要快得多。https://opensignal.com/reports/2016/02/usa/state-of-the-mobile-network网站

    2)HTTP2多路复用https://http2.github.io/faq/为什么-is-http2-multiplexed

    "数据URI"绝对应该考虑用于移动站点。通过蜂窝网络进行HTTP访问的每个请求/响应都具有更高的延迟。因此,在一些用例中,将图像作为数据干扰到CSS或HTML模板中可能对移动Web应用程序有利。您应该根据具体情况来衡量使用情况——我不主张在移动Web应用程序中到处都应该使用数据URI。

    请注意,移动浏览器对可缓存文件的总大小有限制。iOS3.2的限制非常低(每个文件25K),但对于新版MobileSafari,限制越来越大(100K)。所以在包含数据URI时,一定要注意您的总文件大小。

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


    如果您只引用一次该图像,我认为将其嵌入到您的CSS文件中没有问题。但是,一旦您使用了多个图像或需要在CSS中多次引用它,您可以考虑使用单个图像映射,然后您可以从中裁剪单个图像(请参见CSS精灵)。


    我建议使用两个单独的样式表:一个包含常规样式定义,另一个包含base64编码的图像。

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

    通过这种方式,您可以确保您的常规样式表被下载并尽快应用到文档中,同时您还可以从减少的HTTP请求和其他好处中获益。


    base64在gzipped之后增加了大约10%的图像大小,但这超过了移动方面的好处。由于响应式Web设计有一个总体趋势,因此强烈推荐使用。

    W3C还建议对移动设备使用这种方法,如果在Rails中使用资产管道,这是压缩CSS时的默认功能。

    http://www.w3.org/tr/mwabp/bp保存CSS图像


    我不同意为非编辑图片创建单独的CSS文件的建议。

    假设图像是用于UI的,它是表示层样式,如上所述,如果您使用的是移动UI,那么最好将所有样式保存在一个文件中,这样就可以缓存一次。


    您可以用php()编码它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <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);
    ?>

    来源


    我尝试创建一个CSS/HTML分析器工具的在线概念:

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

    它可以:

    • 下载并分析html/css文件,提取href/src/url元素
    • 在URL上检测压缩(gzip)和大小数据
    • 比较原始数据大小、base64数据大小和gzipped base64数据大小
    • 将URL(image、font、css…)转换为base64数据URI方案。
    • 统计数据URI可以保留的请求数

    欢迎提出意见/建议。

    安东宁


    在我的例子中,它允许我应用CSS样式表,而不必担心复制相关联的图像,因为它们已经嵌入其中。


    为Sublime Text 2的用户带来了一些好处,有一个插件提供了base64代码,我们在ST中加载图像。

    称为image2base64:https://github.com/tm-minty/sublime-text-2-image2base64

    PS:永远不要保存这个插件生成的文件,因为它会覆盖文件并将其销毁。


    据我研究,

    用途:1。使用SVG精灵时。2。当您的图像尺寸较小(最大为200MB)时。

    不要使用:1。当你是更大的图像。2。图标是SVG的。因为它们已经很好了,压缩后会被gzip压缩。


    谢谢你提供的信息。我发现这种嵌入非常有用,尤其是对于移动设备,特别是在缓存嵌入图像的CSS文件时。

    为了让生活更轻松,因为我的文件编辑器本身无法处理这个问题,我为笔记本电脑/桌面编辑工作制作了两个简单的脚本,在这里共享,以防它们对其他人有用。我一直坚持使用PHP,因为它可以直接非常好地处理这些事情。

    在Windows 8.1下说---

    1
    2
    C:\Users\`your user name`\AppData
    oaming\Microsoft\Windows\SendTo

    …作为管理员,您可以在路径中建立批处理文件的快捷方式。该批处理文件将调用php(cli)脚本。

    然后,您可以右键单击文件资源管理器中的图像,并发送到批处理文件。

    确定admiinstartor请求,然后等待黑色命令shell窗口关闭。

    然后只需将剪贴板中的结果粘贴到文本编辑器中…

    1
    <img src="|">

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

    以下内容应适用于其他操作系统。

    批处理文件…

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

    如果路径中有php.exe,则调用php(cli)脚本…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?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));

    ?>