SVG Optimization Best Practices for Web (2025)
How to optimize SVG files for the web. Covers SVGO, manual optimization techniques, inline vs external SVG, accessibility, animation performance, and free online SVG tools.
SVG is the native format for scalable web graphics — icons, logos, charts, illustrations — and it’s often the most overlooked performance opportunity on a page. A fresh Figma export can be 10x larger than it needs to be.
This guide covers how to optimize SVGs systematically: automated tools, manual techniques, delivery strategies, and common mistakes to avoid.
Why SVG Optimization Matters
An unoptimized SVG from a design tool contains:
- Editor metadata (
<sodipodi:namedview>,<dc:format>, etc.) - Unused definitions and symbols
- Redundant
idattributes - Default attribute values that browsers assume anyway
- Unnecessary whitespace and comments
- Verbose path data (more decimal places than needed)
- Empty groups and redundant
transformattributes
A typical Figma icon export might be 4KB. After optimization: 800 bytes. Multiply that across 50 icons on a page.
Tool 1: SVGO (The Standard)
SVGO (SVG Optimizer) is the industry standard for SVG optimization. It’s what most other tools use under the hood.
Install:
npm install -g svgo
Basic usage:
# Optimize a single file (overwrites original)
svgo icon.svg
# Output to a new file
svgo icon.svg -o icon.min.svg
# Optimize all SVGs in a directory
svgo -f ./src/icons/ -o ./dist/icons/
# Show how much was saved
svgo icon.svg --pretty
Configuration file (svgo.config.js):
module.exports = {
plugins: [
'preset-default',
{
name: 'removeViewBox',
active: false, // Keep viewBox for responsive scaling
},
{
name: 'removeDimensions',
active: true, // Remove width/height (use CSS instead)
},
{
name: 'prefixIds',
params: {
prefix: 'icon-', // Prefix IDs to avoid conflicts when inlining
},
},
],
};
Common flags to know:
# Multipass (multiple optimization rounds)
svgo --multipass icon.svg
# Disable a specific plugin
svgo --disable=removeViewBox icon.svg
# Pretty print (readable output)
svgo --pretty icon.svg
Tool 2: Online SVG Optimizers
For one-off optimizations without installing anything:
- SVGOMG (jakearchibald.github.io/svgomg): GUI interface for SVGO with toggle-able plugins and live preview
- Nano SVG (vecta.io/nano): Alternative optimizer with its own algorithm
These are ideal for quickly checking what’s safe to remove before committing to settings.
Manual Optimization Techniques
Some optimizations require human judgment that automated tools can’t make.
1. Remove Unnecessary Metadata
Figma exports include metadata that’s meaningless for web display:
<!-- Remove this -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<sodipodi:namedview />
<rdf:RDF>...</rdf:RDF>
<!-- Keep this -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2. Simplify Paths
Overly precise paths have more decimal places than screens can render:
<!-- Before: 6 decimal places -->
<path d="M12.000000 4.000000 L20.000000 20.000000 L4.000000 20.000000 Z"/>
<!-- After: 1-2 decimal places is sufficient -->
<path d="M12 4 L20 20 L4 20Z"/>
SVGO’s roundPathData plugin handles this automatically, but you can set the precision:
{
name: 'roundPathData',
params: { precision: 2 }
}
3. Merge Similar Elements
Design tools often export individual elements that could be combined:
<!-- Before: 3 separate paths with identical fill -->
<path fill="#333" d="M..."/>
<path fill="#333" d="M..."/>
<path fill="#333" d="M..."/>
<!-- After: one group with the shared attribute -->
<g fill="#333">
<path d="M..."/>
<path d="M..."/>
<path d="M..."/>
</g>
4. Replace Generic Shapes With SVG Primitives
Design tools sometimes export rectangles and circles as <path> elements. Replace them with semantic SVG:
<!-- Instead of a path that draws a circle -->
<path d="M 100 50 A 50 50 0 1 0 100 50.001 Z"/>
<!-- Use the circle primitive -->
<circle cx="100" cy="50" r="50"/>
Primitives are smaller and more readable.
5. Remove Invisible Elements
Clean up clipping masks and invisible elements:
<!-- Invisible elements waste bytes -->
<rect width="24" height="24" fill="none"/> <!-- Remove -->
<path opacity="0" d="..."/> <!-- Remove -->
Inline SVG vs External SVG
Use Inline SVG When:
- Icons that change color via CSS (
:hover, dark mode) - SVGs that need JavaScript interaction
- Critical above-the-fold icons (saves an HTTP request)
- Animated SVGs
<!-- Inline: directly in HTML, styleable via CSS -->
<button class="btn">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>
Download
</button>
/* Color via CSS parent */
.btn:hover svg path {
fill: white;
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
svg path { fill: #e2e8f0; }
}
Use External SVG When:
- Illustrations and complex graphics (cacheable)
- SVGs used as
<img>tags (no JS needed) - SVGs reused across many pages
<!-- External: cached by browser, simpler markup -->
<img src="/icons/logo.svg" alt="Company Logo" width="120" height="40">
SVG Sprite for Icon Systems
For many icons, a sprite reduces HTTP requests:
<!-- sprite.svg (loaded once) -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-search" viewBox="0 0 24 24">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</symbol>
<symbol id="icon-user" viewBox="0 0 24 24">
<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</symbol>
</svg>
<!-- Usage anywhere in the page -->
<svg aria-hidden="true"><use href="#icon-search"/></svg>
<svg aria-hidden="true"><use href="#icon-user"/></svg>
SVG Accessibility
Don’t forget accessibility when embedding SVGs:
<!-- Decorative icons (no semantic value) -->
<svg aria-hidden="true" focusable="false">
<path d="..."/>
</svg>
<!-- Meaningful icons without visible text -->
<svg role="img" aria-labelledby="icon-title">
<title id="icon-title">Search</title>
<path d="..."/>
</svg>
<!-- SVG with visible label -->
<button>
<svg aria-hidden="true">
<path d="..."/>
</svg>
<span>Search</span>
</button>
Rule of thumb: if there’s visible text describing the action, use aria-hidden="true" on the SVG. If the SVG is the only indicator of meaning, add a <title>.
SVG Animation Performance
Animations have their own performance considerations:
CSS Animations (Preferred)
/* High-performance: only animates transform and opacity */
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-icon {
animation: spin 1s linear infinite;
/* Promote to GPU layer */
will-change: transform;
}
SMIL Animations (Avoid in Production)
SMIL (built-in SVG animations) has inconsistent browser support and poor performance. Prefer CSS or JavaScript (GSAP) animations instead.
Reduce Motion
Always respect the user’s motion preference:
@media (prefers-reduced-motion: reduce) {
.animated-icon {
animation: none;
}
}
Build Pipeline Integration
Vite/webpack with vite-plugin-svgr
// vite.config.js
import svgr from 'vite-plugin-svgr';
export default {
plugins: [svgr()],
};
// Usage in React
import { ReactComponent as SearchIcon } from './search.svg';
function SearchButton() {
return (
<button>
<SearchIcon className="icon" aria-hidden="true" />
Search
</button>
);
}
SVGO in package.json scripts
{
"scripts": {
"optimize-icons": "svgo -f src/icons/ -o public/icons/ --multipass",
"prebuild": "npm run optimize-icons"
}
}
Quick Optimization Checklist
Before shipping an SVG:
- Ran through SVGO with
--multipass -
viewBoxpreserved (for responsive scaling) -
width/heightremoved (let CSS control size) - No editor metadata (Inkscape, Illustrator namespaces)
- IDs prefixed if used inline (avoid collisions)
- Accessibility attributes set (
aria-hiddenoraria-label) - Reduced motion considered for animated SVGs
- Paths rounded to 1-2 decimal places
Related Tools
- DevPlaybook Color Contrast Checker — Verify SVG colors meet WCAG contrast requirements
- DevPlaybook CSS Animation Generator — Generate CSS animations for SVG elements
- DevPlaybook Code Formatter — Clean up SVG source code formatting
Download the Frontend Performance Checklist
The Frontend Performance Audit Checklist covers SVG optimization alongside image formats, font loading, bundle splitting, and Core Web Vitals — a complete audit you can run on any web project.
Free Newsletter
Level Up Your Dev Workflow
Get new tools, guides, and productivity tips delivered to your inbox.
Plus: grab the free Developer Productivity Checklist when you subscribe.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links — we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.