Minifying SVG with SVGO profiles in the browser
Published: 2026-09-05
What SVGO actually changes in SVG markup, how safe vs balanced vs aggressive profiles differ, and when to keep titles, IDs, and dimensions before shipping icons.
SVG minification is not a JPEG-style quality slider. You are editing XML markup—paths, attributes, and metadata—so the file stays a vector document while shedding bytes that browsers do not need to draw the shape. The usual engine for that cleanup is SVGO: a pipeline of plugins that strip cruft, shorten path data, and optionally drop accessibility or layout attributes you might still want.
This guide maps what those plugins tend to change, how Safe / Balanced / Aggressive profiles trade size for safety, and how to minify icons locally without uploading design files.
SVG minify vs image compression
| SVG minify (SVGO) | Raster compress | |
|---|---|---|
| Input | Markup (.svg text) |
Pixels (JPEG, PNG, WebP, …) |
| Goal | Smaller XML; same geometry (ideally) | Fewer bytes via codecs / resize |
| Risk | Broken CSS/id hooks, lost <title>, wrong scaling if viewBox/width mishandled |
Artifacts, soft text (lossy) |
| Typical tool | SVG Minifier | Image Optimizer |
Raster trade-offs live in Lossy vs lossless image compression. SVG is closer to cleaning XML than to re-encoding a photo—see also Validating and formatting XML in the browser for well-formedness outside the SVGO pipeline.
If your next step is a React component (camelCase props, SVGProps), optimize first, then convert: SVG to React: cleanup and JSX patterns and SVG to JSX.
What SVGO usually removes
Design-tool exports are chatty. Common wins:
| Cruft | Why drop it |
|---|---|
| Generator comments / editor stamps | Zero runtime value; noisy diffs |
Unused defs, hidden layers, orphan IDs |
Dead weight after flattening |
| Excess decimal precision in paths | Same shape, fewer characters |
| Default metadata blocks | Rarely needed on the public web |
| Redundant groups / transforms | Fewer nodes for the renderer |
SVGO’s preset-default bundles many of those transforms. You can override individual plugins (keep IDs, skip shape→path conversion, and so on) or add extras like removeTitle and removeDimensions. Running multipass lets later plugins clean up what earlier ones exposed.
Measure savings in UTF-8 bytes of the markup string, not “gzip of a PNG.” A 4 KB export that becomes 1.2 KB of path data is a real bundle win for icon sets even before HTTP compression.
Profiles: safe, balanced, aggressive
Named profiles are just preset-default plus a few overrides. LocalTools’ SVG Minifier exposes three that match common icon workflows:
Safe
- Still strips comments and much of the default cleanup.
- Keeps IDs, descriptions, and original shape elements more often (avoids aggressive
cleanupIds,removeDesc,convertShapeToPath, andmergePathsoverrides). - Use when CSS or JS targets
#icon-foo, when<desc>/ structure matters for a11y, or when path merging has bitten you before.
Balanced (recommended default)
- Straight
preset-default—the same cleanup family used by many SVG→JSX pipelines. - Good default for UI icons destined for a sprite, inline markup, or a component wrapper.
- Prefer this unless you know you need IDs or titles preserved.
Aggressive
- Builds on the default preset, then also removes
<title>andwidth/height, while keepingviewBoxso the graphic still scales with CSS. - Smallest typical output for “paint this glyph and let layout size it.”
- Avoid when you rely on native tooltips from
<title>, or when consumers expect intrinsic pixel dimensions on the root<svg>without CSS.
| Profile | Keeps more of… | Shrinks more by… |
|---|---|---|
| Safe | IDs, desc, discrete shapes | Comments / metadata / mild defaults |
| Balanced | Typical icon essentials | Full preset-default |
| Aggressive | viewBox for scaling |
Titles + width/height (+ preset) |
Rule of thumb: start Balanced, preview the result, then step to Safe if selectors or a11y broke, or Aggressive if you only need a scalable glyph and want maximum byte savings.
Pitfalls worth a second look
currentColorand fills — Optimizers may drop “redundant” fills. If theming depends on inherited color, check the preview after minify.- CSS that keys off
idor element type — Safe (or a custom config) beats Aggressive when stylesheets say#logo path. - Sprites and
<use href="#…">— IDs are load-bearing; do not strip them casually. - Width/height vs viewBox — Aggressive removal of dimensions is fine in CSS-sized icons; it surprises email clients or
<img>tags that expect intrinsic size. - Not a substitute for design QA — Minify, then eyeball edges and strokes at the sizes you ship (especially thin 1px strokes).
Why run SVGO in the browser
Icon packs and brand marks are often pre-release or client-confidential. Pasting them into a random “optimize SVG” upload site is an avoidable leak. A tool that runs SVGO in a Web Worker keeps the markup in your tab—same privacy model as other LocalTools utilities (Why “local only” matters for developer tools).
Byte stats (before / after / percent saved) help you pick a profile without guessing. Live preview catches “looks smaller but broke the glyph” before you commit.
Try it on LocalTools
Paste or drop an .svg into SVG Minifier: choose Safe, Balanced, or Aggressive, compare UTF-8 savings, preview, then copy or download—optimization never leaves the browser.
For React/TSX output after cleanup, use SVG to JSX. For raster photos instead of vectors, see Image Optimizer.