Domotion

optimizeSvg()

Run a structure-preserving SVGO pass over the captured SVG.

Signature

function optimizeSvg(svg: string): string

What it does

Runs SVGO 4.x with a focused, structure-preserving plugin set:

  • convertPathData — shorten path commands, switch to relative, drop unneeded precision (1 decimal for floats, 3 for transforms, makeArcs: false to keep glyph fidelity).
  • convertTransform — collapse adjacent translate / scale / rotate into a single matrix when smaller.
  • minifyStyles — collapse whitespace and shortcuts in inline <style> blocks.
  • removeComments.
  • removeEmptyAttrs.

Crucially, the default SVGO plugins that change structure — removing IDs, collapsing groups, inlining defs — are not enabled. The captured SVG uses IDs to wire up clip paths, gradients, and glyph deduplication, and structural changes can break the rendering.

Effect

Typical reduction: 30–50% smaller. For path-heavy text the wins are biggest; for capture output that's mostly rectangles the wins are smaller.

CaptureBeforeAfter optimizeSvg
Single line of text + a button~14 KB~9 KB
Hero card with badge + gradient~30 KB~17 KB
Three-frame animated SVG (terminal demo)~140 KB~75 KB

Numbers are illustrative; your mileage will vary based on text length and whether path-mode glyphs dominate.

Example

import { writeFileSync } from "node:fs";
import { wrapSvg, optimizeSvg } from "domotion";

const svg   = wrapSvg(elementTreeToSvg(tree, w, h), w, h);
const small = optimizeSvg(svg);
writeFileSync("hero.svg", small);
console.log(`${svg.length} → ${small.length} bytes`);

When not to use it

  • While iterating, especially when diffing captures — optimization reduces decimal precision, which makes SVG diffs noisier. Save it for the final ship step.
  • If you need to post-process the SVG yourself (e.g. find an element by ID, walk the markup), do that before optimization. The IDs are preserved either way, but path data is much harder to reason about after compression.

See also