在前端开发过程中,SVG 图标(可缩放矢量图形)被广泛使用,因为它们具有可伸缩性、清晰的显示效果以及较小的文件大小。使用 SVG 作为图标有很多优势, 尤其是在响应式设计和高分辨率屏幕上的表现。
但是,SVG 图标的制作过程也有很多不便之处。一千个读者就有一千个哈姆雷特,一千个制作者绘制同一个图标也可能会有一千个不同的版本。 尽管 SVG 本身已经足够小了,但是在很多矢量编辑器/软件中,导出来的 SVG 文件会有很多其他冗余信息(当然这里面制作者和导出软件可能都会有问题)。
为了解决这些问题,我们需要一个工具来压缩 SVG 图标,使其更小、更清晰、更易于管理。 所以选择了 SVGO 对图片进行压缩并且使用 SVGR 将 SVG 代码转换为 React Component 。
你可以在这尝试进行 svg 的压缩与转化。
ps: scgr 会默认使用 svgo 帮你压缩 svg 代码。
npx @svgr/cli --typescript --out-dir ./svgicons -- svgrz
压缩效果也是显著:
但是在使用的时候发现了一个问题,有一部分压缩完的 SVG 不能设置宽高,如果设置了宽高,会导致 svg 只有一部分展示。
检查 SVG 代码发现,viewBox 标签不见了。删除掉 viewBox 会导致 SVG 不能正常缩放。可以说这属于是破环性的压缩, 很难理解 svgo 为了 “minimizing number of bytes” 而删除 viewBox 标签。
因为对于 SVG 规范了解的并不够深入,所以不能确定 svgo 压缩是否是正确的,查看 issues 发现很多前端开发都提出了这个问题, 但 svgo 似乎并不想修改。
为了解决这个问题,在压缩 SVG 代码时,我们需要通过配置文件来保留 viewBox 标签。
添加 svgo.config.js
文件
export default {
plugins: [
{
name: "preset-default",
params: { overrides: { removeViewBox: false } },
},
],
};
因为 SVGR 会默认使用 SVGO 进行压缩,所以我们需要使用 --no-svgo
禁止 SVGR 的压缩操作
svgo -f svg/ -o svgrz/ && npx @svgr/cli --typescript --out-dir ./svgicons --no-svgo -- svgrz
到这里,SVG 图标的压缩与转化就完成了。
更多关于 SVGO 压缩 viewBox 标签的讨论: