SVG Optimization
Scalable Vector Graphics are the first choice for icons, logos, illustrations, and data visualizations on the web. Because SVG is XML, it is resolution-independent, styleable with CSS, animatable, and compressible. However, raw SVG exported from design tools is almost always bloated with editor metadata, unnecessary attributes, and redundant groups. Optimizing SVG files is one of the highest-leverage performance wins available.
Hub: Graphics & Web Design Related: Image Optimization | CSS Techniques
Optimizing with SVGO
SVGO (SVG Optimizer) is the industry-standard tool for cleaning SVG files. You can run it without installing globally:
# Optimize a single file
npx svgo input.svg -o output.svg
# Optimize an entire directory
npx svgo -f ./raw-icons -o ./optimized-icons
# Preview what will change without writing
npx svgo input.svg --pretty --indent=2 -o -
SVGO ships with a set of default plugins. You can customize them via a config file:
// svgo.config.js
module.exports = {
plugins: [
'preset-default',
'removeDimensions', // Remove width/height, keep viewBox
{ name: 'removeAttrs', params: { attrs: '(fill|stroke)' } },
{ name: 'addAttributesToSVGElement',
params: { attributes: [{ 'aria-hidden': 'true' }] } },
],
};
Running npx svgo --config svgo.config.js icon.svg applies your custom pipeline. Typical savings range from 20 to 60 percent of the original file size.
Inline SVG vs. the <img> Tag
You have two primary ways to embed SVG in a page.
Inline SVG places the markup directly in the HTML. This gives you full CSS and JavaScript control -- you can target individual paths, animate fills, and respond to hover states. The downside is that inline SVG cannot be cached independently of the HTML document.
<svg role="img" aria-labelledby="chart-title" viewBox="0 0 200 100">
<title id="chart-title">Monthly revenue trend</title>
<polyline points="10,90 50,40 90,60 130,20 170,50 190,10"
fill="none" stroke="currentColor" stroke-width="2" />
</svg>
The <img> tag treats SVG as an external image. The browser caches it like any other asset, but you lose the ability to style its internals with CSS. This approach works well for logos and decorative illustrations that do not need interaction.
<img src="/img/logo.svg" alt="Acme Corp logo" width="120" height="40" />
The viewBox Attribute
viewBox defines the coordinate system for the SVG canvas. It takes four numbers: min-x min-y width height. When you combine viewBox with percentage-based or auto sizing, the SVG scales fluidly to any container.
<!-- Scales to fill its container while preserving a 2:1 aspect ratio -->
<svg viewBox="0 0 200 100" style="width: 100%; height: auto;">
<rect x="0" y="0" width="200" height="100" fill="#0d6efd" />
</svg>
Always keep viewBox and remove explicit width/height attributes if you want the SVG to be responsive. SVGO's removeDimensions plugin automates this.
CSS Animations on SVG
CSS @keyframes work on SVG elements just as they do on HTML elements. You can animate transform, opacity, stroke-dashoffset, and more.
@keyframes draw {
from { stroke-dashoffset: 300; }
to { stroke-dashoffset: 0; }
}
.line-chart polyline {
stroke-dasharray: 300;
animation: draw 1.5s ease-in-out forwards;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
.icon-heart {
transform-origin: center;
animation: pulse 2s infinite;
}
Prefer CSS animations over JavaScript for simple effects -- they run on the compositor thread and do not block the main thread.
SMIL Animation Basics
SMIL (Synchronized Multimedia Integration Language) is SVG's native animation system. It is declarative and lives inside the SVG markup itself.
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="10" fill="tomato">
<animate attributeName="r" values="10;30;10"
dur="2s" repeatCount="indefinite" />
</circle>
<rect x="10" y="10" width="20" height="20" fill="steelblue">
<animateTransform attributeName="transform" type="rotate"
from="0 20 20" to="360 20 20"
dur="4s" repeatCount="indefinite" />
</rect>
</svg>
SMIL has broad support (all modern browsers except legacy IE). It is useful for self-contained animated SVGs that must work without external CSS or JS, such as loading spinners distributed as standalone files.
SVG Accessibility
Making SVG accessible requires explicit effort. Screen readers do not automatically interpret SVG shapes as meaningful content.
For meaningful SVGs, add role="img" and a <title> element:
<svg role="img" aria-labelledby="icon-title" viewBox="0 0 24 24">
<title id="icon-title">Download file</title>
<path d="M12 16l-6-6h4V4h4v6h4z" />
<path d="M4 18h16v2H4z" />
</svg>
For decorative SVGs that convey no information, hide them from the accessibility tree:
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
<path d="M12 2L2 22h20z" />
</svg>
The focusable="false" attribute prevents Internet Explorer and some older Edge versions from adding the SVG to the tab order.
Icon Sprite Systems
Instead of inlining every icon or requesting each one separately, combine them into a sprite sheet using <symbol> and reference them with <use>.
Step 1 -- Build the sprite file (icons/sprite.svg):
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<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.79
l5 4.99L20.49 19l-4.99-5z"/>
</symbol>
<symbol id="icon-menu" viewBox="0 0 24 24">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
</symbol>
</svg>
Step 2 -- Reference icons anywhere in your HTML:
<svg class="icon" aria-hidden="true" focusable="false">
<use href="/icons/sprite.svg#icon-search"></use>
</svg>
Step 3 -- Style with CSS:
.icon {
width: 1.5em;
height: 1.5em;
fill: currentColor; /* Inherits text color */
vertical-align: middle;
}
.icon:hover { fill: var(--color-primary); }
The browser fetches sprite.svg once and caches it. Every <use> reference is virtually zero-cost after that. Automate sprite generation with tools like svg-sprite or svgstore.
By combining SVGO optimization, accessible markup, CSS animations, and a sprite system, you can deliver a rich icon and illustration experience at minimal file-size cost.