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

操作步驟

  1. 開啟 SVG 格式化工具
  2. 貼上或上傳 SVG 程式碼
  3. 點擊「最佳化」按鈕
  4. 查看最佳化前後對比:
    • 原始體積 → 最佳化體積
    • 縮減百分比
  5. 複製最佳化結果或下載

六、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#图片优化#图标#压缩#前端