SVG Optimization: Why Your Vector Files Are 10× Bigger Than They Need to Be
Editor metadata, path precision, and needless groups bloat exported SVGs. What is safe to strip, what breaks, and when an SVG should be inline, external, or a data URI.
Where the bloat comes from
Design tools export SVGs for re-editing, not for shipping. A typical Illustrator or Figma export carries editor namespaces, layer names, hidden elements, empty groups, and — the largest offender — path coordinates at 6+ decimal places. On a 24px icon, coordinates beyond 2 decimals are sub-perceptual: rounding them routinely cuts file size 40–60% with zero visible change.
- Safe to strip: editor metadata, comments,
<title>/<desc>you did not write, default-value attributes, empty groups. - Strip with care:
viewBox(never remove it — it is what makes SVG scale), IDs referenced by<use>, gradients or masks, and accessibility titles you added deliberately. - Transform flattening: merging nested
transform="translate(…)"chains into path data shrinks files but breaks CSS that targeted those groups.
Inline, external file, or data URI?
Inline SVG (pasted into HTML) can be styled and animated with CSS and inherits currentColor — right for icons and logos that respond to theme. External .svg files cache across pages — right for large illustrations. Data URIs embed the SVG inside CSS, avoiding a request but bypassing caching and bloating the stylesheet — right only for tiny, single-use decorations like background patterns.
One rule cuts across all three: gzip loves SVG. The XML is repetitive text, so a 30 KB optimized SVG often ships as 6 KB over the wire. Optimize first, but do not chase bytes the compressor already removes.
SVGs in React and the JSX conversion problem
JSX rejects hyphenated attributes, so stroke-width must become strokeWidth, class becomes className, and inline style strings must become objects. Doing this by hand for a 40-path illustration is misery; automated conversion is the only sane path.