可能不要 Base64 编码 SVG

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

也许您听说过数据 URI。这是一种非常好的方式,可以包含原本需要单独 HTTP 请求的资源。您在数据 URI 中使用的格式可能有所不同。本质上,您只需告诉它内容类型是什么(例如 image/png),分号,然后是该文件的数据。

例如

<img src='data: ... '>

或者

.bg {
  background: url('data: ... ');
}

对于像 PNG 这样的光栅图像,该图像的数据需要采用 Base64 格式。我不是这方面的专家,但据我了解,Base64 在 HTML 或 CSS 等内容中使用是安全的,因为它只使用 64 个已知在这些格式中安全的字符。

左侧是 PNG 的数据,其中包含可能导致 HTML 出现问题的字符。右侧是同一图像的 Base64 编码,所有字符都是安全的。

更好的解释 Stack Overflow 答案 由 Dave Markle 提供

您永远不知道——某些协议可能会将您的二进制数据解释为控制字符(如调制解调器),或者您的二进制数据可能会被破坏,因为底层协议可能认为您输入了特殊的字符组合(例如 FTP 如何转换换行符)。

因此,为了解决这个问题,人们将二进制数据编码成字符。Base64 就是这些编码类型之一。

Base64 看起来像乱码,我们经常将乱码与 Web 上的压缩联系起来。但这种乱码并不是压缩,它实际上比原始数据略大,因为引用 Jon Skeet 在同一 Stack Overflow 线程中的说法

它每 3 个字节的数据需要 4 个字符,加上末尾可能的一些填充。

我不确定 gzip 如何融入其中。但我想说的是 SVG 如何融入其中。

您也可以将数据 URI 用于 SVG。

<img src='data:image/svg+xml; ... '>
.bg {
  background: url('data:image/svg+xml; ... ');
}

对于 SVG,您**不必**将数据转换为 Base64。同样,我不是这方面的专家,但我认为 SVG 语法中没有任何疯狂的字符。它就像 HTML 一样,只是 XML,因此在 HTML 中使用是安全的。

您可以将编码保留为 UTF-8,并将 <svg> 语法直接放在那里!像这样

<img src='data:image/svg+xml;utf8,<svg ... > ... </svg>'>
.bg {
  background: url('data:image/svg+xml;utf8,<svg ...> ... </svg>');
}

因此,因为我们可以这样做,并且我们知道 Base64 通常会增加大小,所以最好这样做,对吧?是的。作为额外的好处,单独保留的 <svg> 语法可以更好地进行 gzip 压缩,因为它比 Base64 更具重复性。假设您想要两个版本的图标,一个红色,一个黄色。您可以使用相同的 SVG 语法进行复制,只需更改填充颜色即可。Gzip 会将其一扫而空。感谢 Todd Parker 提供此提示,这也是 Grunticon 的方法,它将 UTF-8 中的 SVG 数据 URI 放入 CSS 中。

测试

为了测试这一点,我从 IcoMoon 下载了三个 SVG 图标。

cog.svg – 1,026 字节
play.svg – 399 字节
replay.svg – 495 字节

我通过 SVGO 运行它们,以便它们得到很好的优化并准备好作为数据 URI 使用(空格已删除,尽管我认为这并不是绝对必要的)。

cog.svg – 685 字节
play.svg – 118 字节
replay.svg – 212 字节

然后,我通过 Base64 转换器 运行这些文件。

cog.svg – 916 字节 – 原始大小的 133%
play.svg – 160 字节 – 原始大小的 136%
replay.svg – 283 字节 – 原始大小的 134%

所以这说得通,对吧?如果每 3 个字节有 4 个字符,那么它会大 133%,变化来自不均匀的长度以及填充。

无论如何,也许这一切都非常明显。但在我看来,如果您要将数据 URI 用于 SVG,则没有理由将其 Base64 编码。

感谢 Matt Flaschen 几个月前发送的电子邮件,它让我意识到了这个问题。

更新:关于 IE

评论中有很多关于 IE 10/11/Edge 不支持此功能的讨论。它确实支持,只是有点挑剔。这是一个简化的测试用例,在这些版本的 IE 中可以正常工作。请注意第二个示例,它是 URL 编码的,可以正常工作。诀窍是不指定任何编码类型。

更新:“优化的 URL 编码”

Taylor Hunt 进行了更深入的研究,发现可以通过不编码空格和单引号等内容来进一步优化。例如

data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M224%20387.814V512L32 320l192-192v126.912C447.375 260.152 437.794 103.016 380.93 0 521.287 151.707 491.48 394.785 224 387.814z'/%3E%3C/svg%3E