Where the bytes in an exported SVG actually go
An SVG is a text file, which is its great strength and the reason it quietly bloats. Nothing about an XML document tells you it has grown; you have to open it and look. When you do, an icon exported from a vector editor usually turns out to be mostly things that have no effect on the picture at all.
A representative export carries an XML declaration it does not need in a browser, a generator comment naming the application and its version, a <metadata> block describing the editing session, style rules for classes nothing uses, wrapper <g> groups left over from the layer panel, and coordinates specified to six or more decimal places when three render identically. On one icon that is a few hundred wasted bytes and nobody is harmed. On a design system shipping ninety inline icons to every visitor on every page, it is a tax paid over and over, and it lands on both transfer size and parse time.
Cleaning it up is one of the rare page-weight wins that is genuinely free. There is no quality slider to agonise over, because none of the removed material was drawing anything.
What SVGO’s default preset strips, and the two things it keeps
The work here is done by SVGO, the same optimizer that sits inside most build pipelines and design tooling, running its preset-default plugin set with multipass enabled so a second cleaning round can catch what the first one exposed. Nothing bespoke was written to reimplement it; the browser build of the library is imported directly and run in your tab.
That preset does considerably more than delete comments. It converts shapes to paths where a path is shorter, rewrites absolute path commands as relative ones, shortens colours (blue becomes #00f), collapses useless groups, drops unreferenced style blocks and removes attributes whose values were already the default. Its output is deliberately still a valid, re-parseable SVG; the test suite feeds the result back through the parser to prove it.
Two things are kept on purpose. <title> and <desc> survive, because they are what a screen reader announces and what a search engine reads, and shaving forty bytes off an icon by making it anonymous to assistive technology is a bad trade. This tool does not add an override to remove them, and it says so here rather than doing it silently.
It is also worth knowing what those <metadata> blocks can contain before you publish a logo: depending on the editor, the original file path on your disk, the application and version, an author name, or an embedded colour profile. Optimizing a file is a privacy step as much as a size step, and it happens entirely on your own machine here, so a client’s unreleased mark is not uploaded anywhere to have its own author metadata removed.
Choosing a precision, with real numbers
The precision option is the only judgement call. To make it concrete, here are real figures for the fixture this tool’s own test suite uses: a 484 byte Illustrator style export carrying an XML declaration, a generator comment, a <metadata> block, a <title>, a <desc>, an unused style rule, a <rect> and a <path> with coordinates written to six decimal places. Each row is that file put through the exact SVGO configuration this tool ships.
| Precision | Output | Change |
|---|---|---|
| 6 | 273 bytes | 43.6% smaller |
| 3 (default) | 246 bytes | 49.2% smaller |
| 2 | 234 bytes | 51.7% smaller |
| 1 | 226 bytes | 53.3% smaller |
| 0 | 210 bytes | 56.6% smaller |
Two things stand out. Most of the saving is already banked before precision enters the picture, because deleting the declaration, the comment, the metadata and the dead style rule is the bulk of the win. And the curve from 3 down to 0 is shallow: the 36 bytes between them are rarely worth introducing rounding you then have to reason about. That same run also shows the other rewrites happening in the same pass, since the <rect> comes back as a <path> and stroke="blue" comes back as stroke="#00f", while the <title> and <desc> are still there untouched.
The default of 3 is SVGO’s own upstream default and the right answer for icons and UI graphics. Go down to 1 or 2 for large illustrations with thousands of path points, where the per number saving multiplies into something real. Go up to 5 or 6 when coordinates carry meaning beyond display, such as a map, a technical drawing or a file that will become a machine toolpath.
Running a batch, and reading the stats comment
Four steps, and one of them is optional:
- Drop one file or a folder’s worth of
.svginto the box above, or click Choose files. - Set Decimal precision for coordinates/path data (0–6, lower = smaller file) if the default of 3 is not what you want.
- Click the action button, which reads SVG Optimizer.
- Download each result and read the stats comment on its first line.
Files are processed one at a time with the progress bar advancing per file, which is effectively instant for text this small. Each result is offered as a download named after the original with -optimized appended, so icon.svg becomes icon-optimized.svg and your source file is never modified.
The first line of every output is a comment like this:
<!-- svg-optimizer: 1000 -> 500 bytes (50.0% smaller); gzip estimate ~300 bytes -->
The gzip figure is not a rule-of-thumb multiplier. It is produced by actually gzipping the optimized markup with the browser’s native compression API, borrowed from the CSS Minifier, which shares this reporting format. That number is the one to care about if you serve the file over HTTP with compression on, and it explains a result that surprises people: heavy repetition in path data compresses extremely well, so a file that shrinks 40 percent raw may only shrink 15 percent over the wire.
What this will not do for you
SVGO is a text optimizer, so its limits follow from that. It will not rasterize (use SVG to PNG when a platform refuses vectors), it will not vectorize a bitmap (that is PNG to SVG), and it will not recompress a base64 raster image embedded inside the markup, which is the single most common reason an SVG stays stubbornly large. It does not merge multiple files into a sprite sheet, does not subset embedded fonts, and cannot convert text elements to outlines.
It is also strict where a CSS minifier is forgiving. Feed it broken markup and it stops with a clear Invalid SVG file error instead of writing something plausible-looking and corrupt, which is the behaviour you want from a tool whose output you are about to commit. An empty file is the one exception and is handled quietly.

