SVG Optimization: Reduce File Size by 80% (Tools and Code)
SVG files exported from design tools like Figma, Illustrator, and Inkscape are typically 3–10x larger than they need to be. They contain editor metadata, redundant group nesting, high-precision coordinates, embedded fonts, and vendor-specific attributes that browsers simply ignore. Optimizing SVGs is one of the highest-ROI performance improvements for icon-heavy web applications.
Why Unoptimized SVGs Are So Large
When Illustrator exports an SVG, it embeds its own metadata, version information, layer names, color profiles, and often entire fonts. A simple icon that should be 500 bytes arrives at 15KB. Inkscape adds its own namespace attributes and editor-specific elements. Figma is better but still includes unnecessary precision in path coordinates and redundant transform attributes.
A real-world example. Here is what an Illustrator-exported SVG looks like before optimization:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.0.0, SVG Export Plug-In . SVG Version: 6.00 -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" 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:#333333;}
</style>
<g id="XMLID_1_">
<path class="st0" id="XMLID_2_" d="M12.0000000,2.3456789 C12.0000000,..."/>
</g>
</svg>
After optimization with SVGO, the same icon becomes:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="#333" d="M12 2.35C12,..."/>
</svg>
File size reduction: from 2,400 bytes to 380 bytes - an 84% reduction. The visual output is identical.
SVGO: The Standard Tool for SVG Optimization
SVGO (SVG Optimizer) is the industry-standard Node.js tool for automated SVG optimization. It applies dozens of configurable plugins to remove unused elements, collapse unnecessary groups, round coordinates, and minify the output.
Installation and Basic Usage
# Install globally
npm install -g svgo
# Optimize a single file (outputs to stdout)
svgo input.svg -o output.svg
# Optimize in place
svgo icon.svg
# Optimize all SVGs in a directory
svgo -f ./src/icons/ -o ./dist/icons/
# Show what was removed (verbose)
svgo input.svg --pretty -v
Typical SVGO Results
- Simple icons: 60–85% size reduction
- Illustration-style SVGs: 30–60% reduction
- SVGs with embedded raster images: minimal reduction (the raster data dominates)
- Already-optimized SVGs: 5–20% reduction
SVGO Configuration (svgo.config.js)
SVGO v3 uses a configuration file for fine-grained control. Some plugins are destructive (they can alter visual output) and should be enabled with care:
// svgo.config.js
module.exports = {
plugins: [
'preset-default', // All safe default optimizations
'removeDimensions', // Remove width/height, keep viewBox (responsive SVG)
{
name: 'removeAttrs',
params: {
attrs: '(stroke|fill)' // Remove hardcoded colors (apply via CSS instead)
}
},
{
name: 'convertPathData',
params: {
floatPrecision: 2 // Round coordinates to 2 decimal places
}
}
]
};
Caution with these plugins: removeViewBox can break responsive scaling. cleanupIds can break SVG sprites that reference IDs. removeHiddenElems can remove elements that are shown via CSS animation. Always visually diff after optimization on complex SVGs.
Manual SVG Optimizations
SVGO handles most cases automatically, but understanding what it does helps when you need to troubleshoot or manually clean up SVGs that SVGO handles poorly.
1. Remove Editor Metadata
Remove the XML declaration, comments, generator strings, and editor-specific namespaces. None of these affect rendering:
<!-- Remove these: -->
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27... -->
xmlns:xlink="http://www.w3.org/1999/xlink" <!-- if xlink:href is not used -->
xml:space="preserve"
enable-background="new 0 0 24 24"
2. Simplify Path Coordinates
Design tools export path data with extreme precision: M12.0000000,2.3456789. For web icons, 1–2 decimal places is more than sufficient. Reduce coordinate precision to shorten path data significantly:
<!-- Before -->
<path d="M12.0000000,2.3456789 C16.4183099,2.3456789 20.0000000,..."/>
<!-- After (2 decimal places) -->
<path d="M12,2.35 C16.42,2.35 20,..."/>
3. Collapse Unnecessary Groups
Illustrator creates a group for every layer. Groups with no attributes (no transform, no class, no id that is referenced) add nothing:
<!-- Unnecessary wrapper group -->
<g id="Layer_1">
<g id="XMLID_1_">
<path .../>
</g>
</g>
<!-- Simplified -->
<path .../>
4. Use CSS Instead of Inline Styles
When the same color or style is repeated across many elements, move it to a CSS class. This especially matters for SVG sprites where the same file is reused many times:
<!-- Repeated inline fill -->
<path fill="#333333" .../>
<circle fill="#333333" .../>
<rect fill="#333333" .../>
<!-- Better: use CSS or presentational attribute on the root -->
<svg fill="#333" ...>
<path .../>
<circle .../>
<rect .../>
</svg>
5. Remove Hidden and Invisible Elements
Check for elements with display:none, opacity:0, visibility:hidden, or zero-dimension shapes. These are often leftover from editing and serve no visual purpose.
Compress Images and SVGs Online
Upload your images and SVGs for instant compression. Supports PNG, JPEG, WebP, and SVG. No software to install, runs in your browser, files never leave your device.
Open Image Compressor →Inline SVG vs External SVG File
How you include SVGs in a page affects performance significantly:
External File (<img src="icon.svg"> or CSS background-image)
- Browser caches the file independently
- Cannot be styled with CSS (fill, stroke colors)
- Cannot be animated with CSS or JS that targets inner elements
- Best for: decorative images, illustrations, logos where styling is not needed
Inline SVG (embedded in HTML)
- No additional HTTP request (saves a round-trip)
- Full CSS styling access (change fill color on hover, etc.)
- Full JS access to inner elements for animation
- Increases HTML document size (not separately cacheable)
- Best for: icons, interactive graphics, anything styled or animated
SVG Sprite (single file, multiple symbols)
<!-- sprite.svg -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z"/>
</symbol>
<symbol id="icon-user" viewBox="0 0 24 24">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</symbol>
</svg>
<!-- Usage -->
<svg><use href="sprite.svg#icon-search"/></svg>
<svg><use href="sprite.svg#icon-user"/></svg>
SVG sprites load one file and reference symbols by ID. One HTTP request, full CSS styling, cached by the browser. This is the recommended approach for icon systems with 10+ icons.
Step-by-Step: Optimizing an SVG for Production
- Export cleanly from your design tool. In Figma: use "Copy as SVG" or export with "Flatten" enabled. In Illustrator: export with "Use Artboards" and "CSS Properties: Presentation Attributes".
- Run SVGO.
npx svgo input.svg -o output.svg. Check the size reduction output. - Visually verify. Open both files in a browser and compare. Check at multiple sizes (16px, 32px, 64px) for icons.
- Apply gzip/Brotli compression. SVGs are text and compress extremely well. A 1KB optimized SVG compresses to ~400 bytes with Brotli. Configure your web server to serve SVGs with
Content-Encoding: br. - Choose the right delivery method. Inline for interactive/styled icons, external file + cache headers for illustrations, sprite for icon libraries.
- Set cache headers. For external SVG files:
Cache-Control: public, max-age=31536000, immutable(with hashed filenames for cache busting).
SVG and Core Web Vitals
SVGs can affect your Core Web Vitals in several ways:
- LCP (Largest Contentful Paint): If a large SVG illustration is the LCP element, its load time directly impacts your score. Use
<link rel="preload" as="image" href="hero.svg">to preload critical SVGs. - CLS (Cumulative Layout Shift): SVGs without explicit
widthandheightattributes (or aviewBoxplus container CSS) can cause layout shift as they load. Always set dimensions or use theaspect-ratioCSS property. - INP (Interaction to Next Paint): Complex inline SVGs with many DOM nodes can slow rendering. Prefer external SVG files for complex illustrations to keep the DOM lighter.
Use our free tool here → Image Compressor
Frequently Asked Questions
How much can SVGO reduce an SVG file size?
For freshly exported Illustrator or Inkscape files, 60–85% reduction is typical for simple icons. Complex illustrations with gradients and many paths see 30–60% reduction. SVGO reports the percentage saved after each run. The biggest wins come from removing editor metadata, collapsing redundant groups, and reducing coordinate precision.
Will SVGO change the appearance of my SVG?
With the default preset-default configuration, SVGO makes only safe transformations that do not change visual output. Some aggressive plugins (removeViewBox, mergePaths on complex shapes, convertShapeToPath with tight tolerances) can occasionally produce subtle differences. Always visually compare after optimization, especially for icons that use masks, clip-paths, or gradients.
Should I use SVG or PNG/WebP for icons?
For icons used at multiple sizes (16px to 64px), SVG is almost always the better choice. SVGs are resolution-independent (look sharp on any screen density), can be styled with CSS (color themes, hover states), and are typically smaller than a set of PNG icons at multiple resolutions. Use PNG or WebP only when the image is photographic or contains effects that SVG cannot replicate cleanly.
How do I make an SVG icon change color on hover with CSS?
Inline the SVG and set fill="currentColor" on the paths. Then control the color via CSS color property on the parent element: .icon { color: #333; } .icon:hover { color: #0066cc; }. This works because currentColor inherits the CSS color value, making SVG icons as easy to style as text.
What is the best way to handle SVG icons in a React or Vue app?
In React, import SVGs as components (Vite/webpack can handle this with the appropriate plugin) to get inline SVG with currentColor support. Alternatively, use a pre-built icon library like Heroicons or Lucide that exports React components wrapping optimized inline SVGs. For Vue, use vue-svg-inline-loader or similar. Avoid loading SVGs as <img> tags in component-heavy apps where you need CSS control over icon colors.
How do I use SVGs in email templates?
SVG is not supported in most email clients (Outlook, older Gmail versions). For email, convert critical SVGs to PNG at 2x resolution for retina displays, and provide a 1x fallback. Use the srcset attribute in supported clients for responsive images. For logos and simple shapes, consider using web fonts or Unicode characters as a fallback.
Usman has 10+ years of experience securing enterprise infrastructure, managing high-traffic servers, and building zero-knowledge security tools. Read more about the author.