SVG Optimization: Reduce File Size by 80%

Your exported SVGs are bloated. Design tools add metadata, redundant groups, and unnecessary precision that inflate file sizes. Here is how to fix that, with code examples and measurable results.

Why SVGs Need Optimization

SVG is the format of choice for icons, logos, illustrations, and UI elements on the web. It scales to any resolution, supports CSS styling, and weighs less than raster alternatives at most sizes. But the SVGs you export from Figma, Illustrator, or Sketch are not production-ready. They are bloated.

A typical icon exported from Figma at 24x24px might weigh 2-4 KB. After optimization, that same icon is 200-600 bytes. When you multiply that by 50 or 100 icons across a site, the difference is meaningful: tens of kilobytes saved on every page load.

Optimization is not just about file size. Cleaner SVG markup is easier to read, easier to style with CSS, easier to animate, and less likely to cause rendering issues across browsers.

Real-World Example

A set of 48 icons exported from Figma totaled 187 KB. After running through SVGO with a tuned configuration, the set measured 34 KB — an 82% reduction. With gzip compression on the server, the transfer size dropped to 11 KB.

What Bloats Your SVGs

Before you can optimize, you need to understand what you are removing. Design tools add a substantial amount of data that serves the editor but does nothing for the browser.

Common Sources of Bloat

Bloat Type Example Impact
Editor metadata Illustrator's <!-- Generator: Adobe Illustrator -->, Figma IDs 50-500 bytes per file
Unnecessary attributes xmlns:xlink, xml:space, data-name 100-300 bytes per file
Excessive precision Coordinates like 12.000000001 instead of 12 20-40% of path data size
Redundant groups Nested <g> elements with no attributes 50-200 bytes per file
Embedded styles Full <style> blocks instead of attributes 100-1000+ bytes
Hidden elements display="none", off-canvas elements, clip masks Variable, can be large
Unoptimized paths Absolute coordinates when relative would be shorter, full moveto commands 10-30% of path data size

Here is what a typical unoptimized SVG icon looks like compared to its optimized version.

svg — Before Optimization (1,847 bytes)
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 28.0, SVG Export -->
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     version="1.1"
     id="Layer_1"
     x="0px" y="0px"
     viewBox="0 0 24 24"
     style="enable-background:new 0 0 24 24;"
     xml:space="preserve">
  <style type="text/css">
    .st0{fill:none;stroke:#000000;stroke-width:2;
         stroke-linecap:round;stroke-linejoin:round;}
  </style>
  <g id="search-icon">
    <g>
      <circle class="st0" cx="11.000000" cy="11.000000"
              r="8.000000"/>
      <line class="st0" x1="21.000000" y1="21.000000"
            x2="16.650000" y2="16.650000"/>
    </g>
  </g>
</svg>
svg — After Optimization (198 bytes)
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
     viewBox="0 0 24 24" fill="none" stroke="currentColor"
     stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <circle cx="11" cy="11" r="8"/>
  <path d="m21 21-4.35-4.35"/>
</svg>

Same visual result. 89% smaller. The optimized version also uses currentColor, making it stylable with CSS.

SVGO: The Essential Optimizer

SVGO (SVG Optimizer) is the standard tool for SVG optimization. It applies a configurable pipeline of plugins that strip unnecessary data, simplify paths, and clean up markup.

bash — Install and Run SVGO
# Install globally
npm install -g svgo

# Optimize a single file
svgo input.svg -o output.svg

# Optimize all SVGs in a directory
svgo -f ./src/icons -o ./dist/icons

# Use without installing (npx)
npx svgo input.svg -o output.svg

# Show file size before and after
npx svgo input.svg -o output.svg --pretty --indent 2

Recommended SVGO Configuration

svgo.config.js — Production Config
module.exports = {
  multipass: true,  // Run multiple passes for better optimization
  plugins: [
    // Preset default includes most useful optimizations
    {
      name: 'preset-default',
      params: {
        overrides: {
          // Keep viewBox (needed for responsive scaling)
          removeViewBox: false,

          // Keep IDs if you reference them (sprites, CSS)
          cleanupIds: {
            remove: false,
            minify: true,
          },

          // Round to 2 decimal places (good balance)
          cleanupNumericValues: {
            floatPrecision: 2,
          },

          // Convert absolute paths to relative (saves bytes)
          convertPathData: {
            floatPrecision: 2,
          },
        },
      },
    },

    // Remove width/height for fluid scaling (use viewBox instead)
    'removeDimensions',

    // Sort attributes for consistency and better gzip
    'sortAttrs',

    // Convert colors to shortest form (#fff vs #ffffff)
    {
      name: 'convertColors',
      params: {
        currentColor: true,  // Convert #000 to currentColor
      },
    },
  ],
};
Watch Out

Do not blindly optimize SVGs with embedded text, clip paths, masks, or complex filters. Some SVGO plugins can break these features. Always visually compare before and after, and use multipass: true for the best results without manual checking of intermediate steps.

You can also optimize SVGs right in the browser with QTool's SVG Optimizer — paste or upload any SVG file and get an optimized version instantly, no CLI required.

Manual Optimization Techniques

SVGO handles the automated cleanup, but some optimizations require human judgment. These manual techniques can yield additional savings beyond what automated tools achieve.

1. Simplify Paths

Complex paths with hundreds of anchor points can often be simplified to a fraction of their original point count without visible difference. In your vector editor, look for "Simplify Path" (Illustrator) or "Flatten" (Figma) options.

2. Use Basic Shapes Instead of Paths

svg — Path vs Shape Element
<!-- Verbose: circle as a path (109 bytes) -->
<path d="M22,12A10,10,0,1,1,12,2,10,10,0,0,1,22,12Z"/>

<!-- Efficient: circle element (35 bytes) -->
<circle cx="12" cy="12" r="10"/>

<!-- Verbose: rectangle as a path (87 bytes) -->
<path d="M2,4H22V20H2Z"/>

<!-- Efficient: rect element (43 bytes) -->
<rect x="2" y="4" width="20" height="16"/>

3. Combine Similar Paths

Multiple paths that share the same fill and stroke attributes can often be combined into a single path element. This eliminates repeated attribute declarations.

4. Remove Hidden Layers and Off-Canvas Elements

Design files frequently contain hidden layers, guides, and elements positioned outside the viewBox. These add bytes without contributing to the visual output. Manually review and delete them before export.

5. Optimize Coordinate Precision

svg — Precision Reduction
<!-- Before: 6 decimal places (74 bytes) -->
<path d="M12.482931,3.219847 L21.938472,14.726194 L3.027390,14.726194Z"/>

<!-- After: 1 decimal place (56 bytes) -->
<path d="M12.5,3.2 L21.9,14.7 L3,14.7Z"/>

<!-- Even shorter: integers where possible (46 bytes) -->
<path d="M12.5 3.2 21.9 14.7H3Z"/>

For most icons at 24x24 viewBox, one decimal place is more than sufficient. For large illustrations, two decimal places preserve quality while saving substantial bytes.

Inline SVG vs External Files

How you embed SVGs affects performance, cacheability, and styling capabilities. There is no single best approach — each method has trade-offs.

Method Caching CSS Styling Best For
Inline SVG No (part of HTML) Full (fills, strokes, transforms) Icons, logos, interactive elements
<img src> Yes (browser cache) None Decorative images, complex illustrations
CSS background-image Yes (CSS cache) None Background patterns, textures
<object> Yes Internal CSS only Interactive SVGs with embedded scripts
SVG sprite + <use> Yes (if external) Partial (currentColor) Icon systems with many repeated icons
html — Inline SVG (Fully Stylable)
<!-- Icon inherits color from parent via currentColor -->
<button class="btn-primary">
  <svg width="20" height="20" viewBox="0 0 24 24"
       fill="none" stroke="currentColor" stroke-width="2">
    <path d="M5 12h14M12 5l7 7-7 7"/>
  </svg>
  Continue
</button>

<style>
.btn-primary { color: #00d4ff; }
.btn-primary:hover { color: #818cf8; }
/* The SVG stroke color changes automatically */
</style>

SVG Sprite Sheets

When you use many icons across your site, an SVG sprite sheet consolidates all icons into a single file. Each icon is defined once and referenced with the <use> element.

svg — Sprite Sheet (icons.svg)
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  <symbol id="icon-search" viewBox="0 0 24 24">
    <circle cx="11" cy="11" r="8" fill="none"
            stroke="currentColor" stroke-width="2"/>
    <path d="m21 21-4.35-4.35" fill="none"
          stroke="currentColor" stroke-width="2"/>
  </symbol>

  <symbol id="icon-menu" viewBox="0 0 24 24">
    <path d="M3 12h18M3 6h18M3 18h18" fill="none"
          stroke="currentColor" stroke-width="2"/>
  </symbol>

  <symbol id="icon-close" viewBox="0 0 24 24">
    <path d="M18 6 6 18M6 6l12 12" fill="none"
          stroke="currentColor" stroke-width="2"/>
  </symbol>
</svg>
html — Using Sprite Icons
<!-- Reference icons from the sprite -->
<svg width="24" height="24">
  <use href="icons.svg#icon-search"/>
</svg>

<svg width="24" height="24">
  <use href="icons.svg#icon-menu"/>
</svg>

<!-- Or inline the sprite in the HTML and reference locally -->
<svg width="24" height="24">
  <use href="#icon-close"/>
</svg>

Styling SVGs with CSS

One of SVG's biggest advantages over raster formats is CSS styling. You can change colors, add hover effects, animate elements, and apply responsive sizing — all without touching the SVG file.

css — SVG Styling Techniques
/* Inherit text color for mono icons */
.icon {
  width: 1.25em;
  height: 1.25em;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.125em;  /* Align with text baseline */
}

/* Hover effect */
.btn:hover .icon {
  stroke: var(--primary-hover);
  transform: translateX(2px);
  transition: stroke 0.2s, transform 0.2s;
}

/* Dark/light mode with CSS custom properties */
:root {
  --icon-primary: #1a1a2e;
  --icon-secondary: #6b6b8a;
}
@media (prefers-color-scheme: dark) {
  :root {
    --icon-primary: #e2e8f0;
    --icon-secondary: #94a3b8;
  }
}

.icon-brand { fill: var(--icon-primary); }
.icon-muted { stroke: var(--icon-secondary); }

Use QTool's SVG to CSS converter to turn SVG files into CSS background-image data URIs, and the SVG Editor to make quick visual adjustments without opening a full design tool.

Animation Performance

SVG animations can be smooth and lightweight, or they can destroy your frame rate. The difference comes down to what you animate and how you animate it.

The Performance Hierarchy

Approach Performance When to Use
CSS transform + opacity Excellent (GPU-accelerated) Hover effects, transitions, simple animations
CSS animation Good Loading spinners, looping animations, keyframed sequences
SMIL (<animate>) Good (declarative) Path morphing, self-contained animations inside SVG files
JavaScript + rAF Variable Complex interactive animations, data-driven transitions
Animating d, points, fill Poor (triggers repaint) Avoid if possible, or limit to few elements
css — High-Performance SVG Animation
/* GPU-accelerated: only transform and opacity */
.icon-loading {
  animation: spin 1s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Smooth hover with will-change hint */
.animated-icon {
  transition: transform 0.3s ease, opacity 0.3s ease;
  will-change: transform;  /* Use sparingly */
}
.animated-icon:hover {
  transform: scale(1.1);
  opacity: 0.9;
}

/* Draw-on effect using stroke-dasharray */
.draw-path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: draw 1.5s ease forwards;
}
@keyframes draw {
  to { stroke-dashoffset: 0; }
}
Performance Killer

Animating the d attribute (path data) on every frame forces the browser to recalculate the path geometry, re-rasterize, and repaint. If you need path morphing, use a library like Flubber or GSAP MorphSVG that interpolates efficiently, and limit it to 2-3 elements at most.

SVG Accessibility

SVGs need accessibility treatment just like images. The approach depends on whether the SVG is informative or decorative.

html — Accessible SVG Patterns
<!-- Informative inline SVG: use title + aria-labelledby -->
<svg role="img" aria-labelledby="chart-title chart-desc"
     viewBox="0 0 400 200">
  <title id="chart-title">Monthly Revenue</title>
  <desc id="chart-desc">
    Bar chart showing revenue growing from $12K in January
    to $34K in June 2026.
  </desc>
  <!-- Chart elements -->
</svg>

<!-- Decorative inline SVG: hide from screen readers -->
<svg aria-hidden="true" focusable="false" width="24" height="24">
  <!-- Decorative icon -->
</svg>

<!-- SVG in img tag: use alt attribute -->
<img src="diagram.svg" alt="Architecture diagram showing three
     microservices connected through an API gateway">

<!-- Decorative SVG in img tag -->
<img src="decoration.svg" alt="">

Run your SVG-heavy pages through QTool's Accessibility Checker to catch missing labels and roles on SVG elements.

Build Tool Integration

Automate SVG optimization in your build pipeline so every SVG that ships to production is optimized, regardless of who exported it from the design tool.

javascript — Vite Plugin (vite-plugin-svgo)
// vite.config.js
import { defineConfig } from 'vite';
import svgo from 'vite-plugin-svgo';

export default defineConfig({
  plugins: [
    svgo({
      multipass: true,
      plugins: [
        {
          name: 'preset-default',
          params: {
            overrides: {
              removeViewBox: false,
            },
          },
        },
        'removeDimensions',
        'sortAttrs',
      ],
    }),
  ],
});
javascript — Webpack SVG Loader
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          {
            loader: '@svgr/webpack',  // Import SVGs as React components
            options: {
              svgo: true,
              svgoConfig: {
                plugins: [
                  { name: 'removeViewBox', active: false },
                  'removeDimensions',
                ],
              },
            },
          },
        ],
      },
    ],
  },
};
bash — CI Pipeline SVG Optimization
# GitHub Actions: optimize SVGs on push
name: Optimize SVGs
on:
  push:
    paths: ['**/*.svg']

jobs:
  optimize:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npx svgo -r -f ./src/assets/icons
      - run: |
          git config user.name "SVG Bot"
          git config user.email "bot@example.com"
          git add -A
          git diff --cached --quiet || git commit -m "chore: optimize SVGs"
          git push

SVG Tools

QTool provides free browser-based SVG tools that require no installation or signup.

Optimize Your SVGs Right Now

Drop any SVG into QTool's SVG Optimizer for instant optimization. No signup, no installation, works in your browser.

SVG Optimizer All Free Tools

Frequently Asked Questions

SVG optimization can typically reduce file size by 40-80% depending on the source. SVGs exported from design tools like Figma, Illustrator, or Sketch contain substantial metadata, editor-specific attributes, redundant groups, unnecessary precision in coordinates, and embedded fonts or styles that are not needed for web display. Running these files through SVGO with default settings usually achieves 40-60% reduction. Adding manual optimizations like simplifying paths, removing hidden layers, and converting shapes to more efficient path syntax can push savings to 80% or more.

Use inline SVGs for icons, logos, and illustrations that need CSS styling or JavaScript interaction, as they become part of the DOM and can be styled with CSS custom properties, animated, and made interactive. Use external SVG files (via img tag or CSS background-image) for decorative images, complex illustrations that do not need interactivity, and SVGs that appear on multiple pages (since the browser can cache external files). A hybrid approach using an SVG sprite sheet with the use element offers a good balance of cacheability and styling control.

SVGO (SVG Optimizer) is a Node.js-based tool that optimizes SVG files by applying a series of plugins that clean up and compress SVG markup. It removes metadata, comments, editor artifacts, unnecessary attributes, empty elements, and redundant transforms. You can use it as a CLI tool (npx svgo input.svg -o output.svg), as a build tool plugin (webpack, Vite, Rollup), or programmatically in Node.js. SVGO is configurable through a svgo.config.js file where you can enable or disable specific optimization plugins based on your needs.

SVG animations can significantly affect page performance if not implemented carefully. CSS animations on SVG properties like transform and opacity are hardware-accelerated and perform well. SMIL animations (animate, animateTransform elements) are declarative and generally efficient but have limited browser control. JavaScript animations using requestAnimationFrame work well for complex sequences but can cause jank if they trigger layout recalculations. Avoid animating SVG attributes that trigger repaints on every frame, such as d (path data), points, width, height, or fill on large numbers of elements. For best performance, prefer CSS transforms, use will-change sparingly, and limit animated elements to under 100 per viewport.

Use SVG for graphics that consist of shapes, lines, and text: logos, icons, illustrations, charts, diagrams, maps, and UI elements. SVGs scale to any resolution without quality loss, are typically smaller than equivalent PNGs at high resolutions, and can be styled and animated with CSS. Use PNG or WebP for photographs, complex textures, screenshots, and images with many color gradients that would create extremely complex paths in SVG. A good rule: if you could reasonably draw it in a vector editor, use SVG. If it was captured by a camera or has photographic detail, use a raster format.

For inline SVGs, add role="img" and an aria-labelledby attribute that references a title element inside the SVG. The title element provides the accessible name. For complex SVGs, add a desc element for a longer description. For decorative SVGs that convey no information, use aria-hidden="true" to hide them from screen readers entirely. For SVGs used in img tags, use the alt attribute just like any other image. Example: use svg with role="img" and aria-labelledby="chart-title chart-desc" alongside title and desc elements inside.

NT

Christian Bucher

We build free browser-based developer tools. Our SVG tools are used by designers and developers to optimize, convert, and edit vector graphics without leaving the browser.

Clean Output on Every Tool

Browse 269 indexed tool pages with no QTool account required, and inspect the source on GitHub.

Open Source — Free Forever Try Free Tools

Related Tools

CSS Box Shadow Generator · Emoji Picker & Search · Free JSON to YAML Converter

Related Tools

Free JSON to YAML Converter · YAML to JSON Converter · Free API Mock Server

Related Articles

Built by Miguel

Need a custom tool or website?

From . Delivered in 24-48h. You own the code.

View Services →