加载 svg
前言
svg 作为矢量图的一种标准格式,已经得到了各大浏览器的支持,它也成为了 web 中矢量图的代名词。在网页中采用 svg 代替位图有如下好处:
svg 相对于位图更清晰,在任意缩放的情况下不会破坏图形清晰度,svg 能方便地解决高分辨率屏幕下图像显示不清楚的问题。
在图形线条比较简单的情况下,svg 文件的大小要小于位图,在扁平化 ui 流行的今天,多数情况下 svg 会更小。
图形相同的 svg 比对应的高清图有更好的渲染性能。
svg 采用和 html 一致的 xml 语法描述,灵活性很高。
svg 基本使用方式
html 中嵌入
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<text y=".9em" font-size="80">🚀</text>
</svg>CSS 背景图
body {
background-image: url(/favicon.svg);
}img 标签引入
<img src="/favicon.svg" />svg 工具
使用 url-loader
url-loader 可以把文件的内容经过 base64 编码后注入到 JavaScript 或者 CSS 中去。
注意
由于一般的图片数据量巨大, 经 base64 编码后会变得更大。 所以在使用 url-loader 时一定要注意图片体积不能太大,不然会导致 JavaScript、CSS 文件过大而带来的网页加载缓慢问题。
一般把网页需要用到的小图片资源注入到代码中去,以减少 HTTP 请求次数。
例如 CSS 源码如下:
body {
background-image: url(/favicon.svg);
}被 url-loader 转换后输出的 CSS 会变成这样:
body {
background-image: url(data:image/svg;base64,iVBORw01afer...);
}webpack 配置
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'url-loader',
options: {
// 10KB 以下的文件采用 url-loader
limit: 1024 * 10,
// 否则采用 file-loader,默认值就是 file-loader
fallback: 'file-loader',
},
},
],
},
],
},
}使用 svg-sprite-loader
用于创建 svg 精灵图的 webpack loader。
sprites 会自动呈现并注入到页面中,原理是将多个 svg 合成 svg <symbol>,通过 symbol id 引用图像。
注意
sprites 只需要在项目初始进行一次 http 请求,但在复杂项目中需要注意 sprites 大小。
使用如下
import twitterLogo from './logos/twitter.svg'
// twitterLogo === SpriteSymbol<id: string, viewBox: string, content: string>
// Extract mode: SpriteSymbol<id: string, viewBox: string, url: string, toString: Function>
const rendered = `
<svg viewBox="${twitterLogo.viewBox}">
<use xlink:href="#${twitterLogo.id}" />
</svg>`webpack runtime 配置如下
// webpack >= 2 multiple loaders
{
test: /\.svg$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: filePath => path.basename(filePath)
}
},
'svg-transform-loader',
'svgo-loader'
]
}extract 配置如下 (default false, autoconfigured)
{
// ......
options: {
extract: true,
spriteFilename: svgPath => `sprite${svgPath.substr(-4)}`
}
}使用 svgo
⚙️ Node.js tool for optimizing SVG files
svgo 可以精简压缩文本中的无用信息,对于向量编辑器导出的 svg 文件能压缩 70% 左右(具体表现要看冗余信息量)!
许多应用程序和框架已经依赖或支持 svgo 集成。项目里从 svgo.config.mjs 读取配置。
项目里一般会设置 fill: currentColor 属性,让 svg 颜色跟随父元素的 color 值变化。