SVG Optimization: Shrink Files from 100KB to 10KB

Utilities

Why SVG Optimization Matters

An unoptimized SVG carries a lot of redundant information — editor metadata, default attributes, excessive precision, and whitespace.

Source Typical size After optimization Reduction
Figma export 45KB 5KB 89%
Illustrator export 80KB 8KB 90%
Inkscape export 120KB 12KB 90%
Hand-written SVG 15KB 3KB 80%

1. Cleaning Up Redundant Information

Editor Metadata

<!-- Redundant information generated by 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 etc. are all useless -->
</svg>

<!-- After optimization -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
</svg>

Default Attributes

<!-- Default values don't need to be declared explicitly -->
<rect x="0" y="0" width="100" height="100" fill="black" stroke="none" opacity="1"/>

<!-- After optimization -->
<rect width="100" height="100"/>
Attribute Default value Safe to remove when
fill black Inherited from parent
stroke none No stroke
opacity 1 Fully opaque
x / y 0 At the origin
stroke-width 1 Default width
font-size Inherited Same as parent

2. Path Optimization

Reducing Precision

<!-- 6 decimal places is overkill -->
<path d="M12.345678 23.456789 L34.567890 45.678901"/>

<!-- 2 decimal places is usually enough (SVG coordinate units) -->
<path d="M12.35 23.46L34.57 45.68"/>
Precision Size Visual difference
6 digits 100% None
3 digits 60% None (invisible within a 1000px viewport)
2 digits 50% Negligible
1 digit 40% Acceptable for small icons

Merging Commands

<!-- Multiple L commands can be merged -->
<path d="M10 20 L30 40 L50 60 L70 80"/>

<!-- After merging (implicit L) -->
<path d="M10 20 30 40 50 60 70 80"/>

Simplifying Curves

<!-- Complex Bézier curve -->
<path d="M0 0C0.12 0.34 0.45 0.67 1 1C1.34 1.23 1.56 1.78 2 2"/>

<!-- If the curvature is nearly a straight line, simplify to L -->
<path d="M0 0L1 1 2 2"/>

3. Merging Shapes

Merging Elements with Identical Styles

<!-- Three circles with the same style -->
<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"/>

<!-- Merged into a single 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"/>

Reusing with <use>

<!-- Reference repeated elements with <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"/>

4. Automated Optimization with SVGO

Installation

npm install -g svgo

Command-Line Usage

# Optimize a single file
svgo input.svg

# Specify output
svgo input.svg -o output.svg

# Batch optimization
svgo -f ./icons/

# Show optimization results
svgo input.svg --show-results

Configuration File

// svgo.config.js
module.exports = {
  multipass: true,  // Multiple optimization passes
  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',  // Remove width/height, rely on viewBox
    'removeViewBox',     // Or keep viewBox and remove 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); // The optimized SVG

5. Optimizing SVG with ToolsKu

Steps

  1. Open the SVG Formatter
  2. Paste or upload your SVG code
  3. Click the "Optimize" button
  4. Review the before-and-after comparison:
    • Original size → optimized size
    • Reduction percentage
  5. Copy the optimized result or download it

6. SVG Sprite Optimization

Inline Sprite

<!-- Hidden SVG definitions -->
<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>

<!-- Usage -->
<svg><use href="#icon-home"/></svg>
<svg><use href="#icon-search"/></svg>

Generating Sprites Automatically

// Generate sprites automatically with svg-sprite
const SVGSprite = require('svg-sprite');

const config = {
  mode: {
    symbol: true,  // Generate in <symbol> mode
  },
  svg: {
    xmlDeclaration: false,
    doctypeDeclaration: false,
  },
};

const spriter = new SVGSprite(config);
// Add SVG files and compile

7. Performance Optimization Checklist

Optimization Effect Priority
Remove editor metadata -20~40% P0
Reduce numeric precision -10~30% P0
Merge path commands -5~15% P1
Remove default attributes -5~10% P1
Convert shapes to paths -5~10% P2
Remove whitespace/comments -2~5% P2
Gzip/Brotli compression -50~70% P0

Note: SVG is a text format, so Gzip/Brotli works extremely well — make sure to enable it on your server.

#SVG#图片优化#图标#压缩#前端