我应该将图片作为data/base64嵌入CSS或HTML中吗?

138

为了减少对服务器的请求量,我将一些图片(PNG & SVG)直接作为BASE64嵌入到CSS中。(这是构建过程中自动完成的)

示例:

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

这是一个好的实践方法吗?有什么避免使用它的理由吗?是否有一些主要的浏览器不支持data url?

附加问题: 对于CSS和JS来说这样做有意义吗?


1
现在很少有人使用IE7了,尽管它有很多缺点,但好处是非常明显的——需要管理的图像文件更少!例如,如果您需要为树组件绘制特殊的线条,则将微小的弯曲图像嵌入到CSS本身中,并与repeat-x或repeat-y结合使用,就可以避免确保额外的图像文件放置在正确的位置(对于这种用例来说,开销非常小)。 - DaveAlger
7个回答

161
这是一个好的实践吗?有一些原因要避免使用它吗?
通常仅适用于非常小的CSS图像(如CSS精灵),当IE兼容性不重要时,保存请求比可缓存性更重要。它有许多明显的缺点:
- 在IE6和7中根本不起作用。 - 仅适用于IE8中大小不超过32k的资源。这是在Base64编码后适用的限制。换句话说,长度不超过32768个字符。 - 它可以节省请求,但会膨胀HTML页面!并使图像无法缓存。每次加载包含页面或样式表的内容时都会加载它们。 - Base64编码使图像大小膨胀33%。 - 如果在经过gzip压缩的资源中提供,data:图像几乎肯定会对服务器资源造成巨大的压力!传统上,压缩图像需要很高的CPU计算量,而且几乎没有缩小的空间。

2
@meo 有趣的观点。我认为这对gzip性能不利,因为图像通常已经被优化压缩了。将它们压缩会消耗可怕的CPU空间,而只能获得个位数的增益。尝试压缩JPG文件,你就会知道你的意思了。我会将其编辑到答案中。 - Pekka
2
@meo 不,无论什么情况下,在base64上它都不会更有效,因为底层模式仍然是压缩的图像数据,只是以base64表示法表达而已。 - Pekka
6
当你像问题所示地将图像嵌入CSS文件中时,它不会使HTML页面变得臃肿。 - Daniel Beardsley
1
根据这个问题(看起来相似或相同)https://dev59.com/YnNA5IYBdhLWcg3wBo9m,您的图像会随着CSS文件的缓存而被缓存。@Pekka웃,您能告诉我们为什么您认为base64编码内容是不可缓存的吗? - F Lekschas
1
通过在 CSS 样式表中嵌入图片,@Flek 可以将其视为一个整体资源而无法缓存。当样式表中的任何内容发生变化时,整个文件(包括图片)都必须重新加载,而如果保持分开,则 CSS 样式表通常只有几千字节大小。 - Pekka
显示剩余11条评论

42
常见的答案似乎表明这不是必要的,有一些合法的理由。 然而,所有这些都似乎忽略了现代应用程序的行为和构建过程。
设计一个简单的流程来遍历一个包含图像的文件夹,并生成一个包含该文件夹中所有图像的单个CSS是不可能的(实际上非常容易)。
这个CSS将被完全缓存,并显著减少往返服务器的次数,这正如@MemeDeveloper所正确提出的那样,是最大的性能损失之一。
当然,这是一个hack。毫无疑问,精灵也是一个hack。在完美的世界中,这将是不必要的,但在现实中,如果您需要解决以下问题,则这是一个可能的做法:
1.页面上有多个图像,这些图像不容易“精灵化”。 2.往返服务器是一个真正的瓶颈(考虑移动端)。 3.对于您的用例,速度(到毫秒级别)确实非常重要。 4.如果您希望Web向前发展,您不关心(就像您应该的那样)IE5和IE6。
这是我的看法。

4
应该给这个帖子点赞以获得更多关注。其他的回答有点过时 - 它们谈论的是IE6,而现在IE8已经过时了... (对此表示感谢) - Hertzel Guinness

10

这不是一个好的实践。一些浏览器不支持数据URI(例如IE 6和7),或者支持受限(例如IE8的32KB)。

参见维基百科上Data URI的完整缺点详述:

缺点

  • Data URIs与包含它们的文档(如CSS或HTML文件)没有单独缓存,因此每次重新下载包含文档时都会下载数据。
  • 每次更改内容都必须重新编码和重新嵌入。
  • Internet Explorer在7版本之前(约2011年1月市场占有率约为15%)不支持。
  • Internet Explorer8将数据URI限制为最大长度为32 KB。
  • 数据被包括为简单流,许多处理环境(如Web浏览器)可能不支持使用容器(如multipart/alternative或message/rfc822)来提供更复杂的元数据、数据压缩或内容协商。
  • Base64编码的数据URI比其二进制等效物大1/3。(然而,如果HTTP服务器使用gzip压缩响应,则这种开销可减少至2-3%)
  • Data URIs使得安全软件更难过滤内容。

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文件。


我已经有了精灵,我想知道是否可以用这种方法进一步优化它。 - meo

2

我不清楚一般最佳实践,但如果可以的话,我个人不希望看到那种情况。 :)

Web浏览器和服务器都内置了很多缓存功能,所以我认为你最好的选择就是让你的服务器告诉客户端缓存图像文件。除非页面上有大量非常小的图像,否则我认为多次请求的开销并不是很大。通常浏览器会使用同一个连接来请求许多文件,因此不会建立新的网络连接,所以除非HTTP头的流量与图像文件的大小相比非常显著,否则不必太担心多次请求。

您认为目前向服务器发送过多请求的原因是什么?


4
请求的数量是性能问题中最大的之一。如果你关心性能,那么应该首先解决这个问题。请参考雅虎的建议: "减少组件的数量可以减少渲染页面所需的HTTP请求数量。这是加速页面的关键。" - MemeDeveloper

1

我建议将其用于非常常用的小图像,例如 Web 应用程序的常见图标。

  • 小,因为 Base64 编码会增加大小
  • 经常使用,因为这可以证明更长的初始加载时间

当然,必须考虑到旧浏览器的支持问题。此外,最好使用框架的功能自动将图像作为数据 URL 内联,例如 GWT 的 ClientBundle,或者至少使用 CSS 类而不是直接将其添加到元素的样式中。

更多信息请参见:http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接