SVG 最佳化完全指南:從 100KB 縮減到 10KB 的精簡技巧
實用工具趙婉清
SVG 最佳化的必要性
未最佳化的 SVG 包含大量冗餘資訊——編輯器元數據、預設屬性、多餘精度、空白字元。
| 來源 | 典型體積 | 最佳化後 | 縮減率 |
|---|---|---|---|
| Figma 匯出 | 45KB | 5KB | 89% |
| Illustrator 匯出 | 80KB | 8KB | 90% |
| Inkscape 匯出 | 120KB | 12KB | 90% |
| 手寫 SVG | 15KB | 3KB | 80% |
一、冗餘資訊清理
編輯器元數據
<!-- Illustrator 產生的冗餘資訊 -->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:serif="http://www.serif.com/"
id="Artboard1"
serif:id="Artboard 1"
viewBox="0 0 800 600">
<!-- serif:id、xmlns:serif 等都是無用的 -->
</svg>
<!-- 最佳化後 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
</svg>
預設屬性
<!-- 預設值無需明確宣告 -->
<rect x="0" y="0" width="100" height="100" fill="black" stroke="none" opacity="1"/>
<!-- 最佳化後 -->
<rect width="100" height="100"/>
| 屬性 | 預設值 | 可移除條件 |
|---|---|---|
fill |
black |
繼承自父元素 |
stroke |
none |
無描邊 |
opacity |
1 |
完全不透明 |
x / y |
0 |
位於原點 |
stroke-width |
1 |
預設寬度 |
font-size |
繼承 | 與父元素相同 |
二、路徑最佳化
精度縮減
<!-- 6 位小數精度過高 -->
<path d="M12.345678 23.456789 L34.567890 45.678901"/>
<!-- 2 位精度通常足夠(SVG 座標系單位) -->
<path d="M12.35 23.46L34.57 45.68"/>
| 精度 | 體積 | 視覺差異 |
|---|---|---|
| 6 位 | 100% | 無 |
| 3 位 | 60% | 無(1000px 視窗內不可見) |
| 2 位 | 50% | 極微 |
| 1 位 | 40% | 小圖示可接受 |
命令合併
<!-- 多個 L 命令可合併 -->
<path d="M10 20 L30 40 L50 60 L70 80"/>
<!-- 合併後(隱式 L) -->
<path d="M10 20 30 40 50 60 70 80"/>
曲線簡化
<!-- 複雜貝茲曲線 -->
<path d="M0 0C0.12 0.34 0.45 0.67 1 1C1.34 1.23 1.56 1.78 2 2"/>
<!-- 如果曲率接近直線,可簡化為 L -->
<path d="M0 0L1 1 2 2"/>
三、形狀合併
相同樣式元素合併
<!-- 三個相同樣式的圓 -->
<circle cx="10" cy="10" r="5" fill="red"/>
<circle cx="30" cy="10" r="5" fill="red"/>
<circle cx="50" cy="10" r="5" fill="red"/>
<!-- 合併為一個 path -->
<path d="M5 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0M25 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0M45 10a5 5 0 1 0 10 0a5 5 0 1 0-10 0" fill="red"/>
<use> 複用
<!-- 重複元素用 <use> 引用 -->
<defs>
<circle id="dot" r="5" fill="red"/>
</defs>
<use href="#dot" x="10" y="10"/>
<use href="#dot" x="30" y="10"/>
<use href="#dot" x="50" y="10"/>
四、使用 SVGO 自動最佳化
安裝
npm install -g svgo
命令列使用
# 單檔案最佳化
svgo input.svg
# 指定輸出
svgo input.svg -o output.svg
# 批次最佳化
svgo -f ./icons/
# 查看最佳化效果
svgo input.svg --show-results
設定檔
// svgo.config.js
module.exports = {
multipass: true, // 多輪最佳化
plugins: [
'removeDoctype',
'removeXMLProcInst',
'removeComments',
'removeMetadata',
'removeEditorsNSData',
'cleanupAttrs',
'mergePaths',
'convertShapeToPath',
'convertTransform',
'removeUnusedNS',
'minifyStyles',
'removeEmptyAttrs',
'removeEmptyContainers',
'removeHiddenElems',
'cleanupNumericValues',
{
name: 'cleanupNumericValues',
params: { floatPrecision: 2 },
},
{
name: 'convertPathData',
params: {
floatPrecision: 2,
transformPrecision: 2,
makeArcs: true,
},
},
'removeDimensions', // 移除 width/height,用 viewBox
'removeViewBox', // 或保留 viewBox,移除 dimensions
],
};
Node.js API
const { optimize } = require('svgo');
const result = optimize(svgString, {
path: 'icon.svg',
multipass: true,
plugins: [
{ name: 'cleanupNumericValues', params: { floatPrecision: 2 } },
],
});
console.log(result.data); // 最佳化後的 SVG
五、使用工具庫最佳化 SVG
操作步驟
- 開啟 SVG 格式化工具
- 貼上或上傳 SVG 程式碼
- 點擊「最佳化」按鈕
- 查看最佳化前後對比:
- 原始體積 → 最佳化體積
- 縮減百分比
- 複製最佳化結果或下載
六、SVG Sprite 最佳化
內嵌 Sprite
<!-- 隱藏的 SVG 定義 -->
<svg style="display:none">
<symbol id="icon-home" viewBox="0 0 24 24">
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
</symbol>
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0016 9.5 6.5 6.5 0 109.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5z"/>
</symbol>
</svg>
<!-- 使用 -->
<svg><use href="#icon-home"/></svg>
<svg><use href="#icon-search"/></svg>
自動產生 Sprite
// 使用 svg-sprite 自動產生
const SVGSprite = require('svg-sprite');
const config = {
mode: {
symbol: true, // 產生 <symbol> 模式
},
svg: {
xmlDeclaration: false,
doctypeDeclaration: false,
},
};
const spriter = new SVGSprite(config);
// 加入 SVG 檔案並編譯
七、效能最佳化清單
| 最佳化項目 | 效果 | 優先級 |
|---|---|---|
| 移除編輯器元數據 | -20~40% | P0 |
| 縮減數值精度 | -10~30% | P0 |
| 合併路徑命令 | -5~15% | P1 |
| 移除預設屬性 | -5~10% | P1 |
| 轉換形狀為路徑 | -5~10% | P2 |
| 移除空白/註解 | -2~5% | P2 |
| Gzip/Brotli 壓縮 | -50~70% | P0 |
注意:SVG 是文字格式,Gzip/Brotli 壓縮效果極佳,務必在伺服器端啟用。
#SVG#图片优化#图标#压缩#前端