Diagnosing When SVGO’s Multipass Optimization Is Needed
Learn how to recognize when a single SVGO pass leaves optimization opportunities, diagnose the cause with a quick table, run ordered checks, apply fixes tied to findings, and know when to escalate.
26 Aug 2026, 02:14 UTC

Recognizable Condition
You run SVGO as part of your build pipeline and notice that the optimized SVG file size is still larger than expected, or visual inspection shows redundant groups (<g>) that could be removed. The SVGO log (or --verbose) reports that the pipeline finished after a single iteration and no further changes were detected.
Cause & Diagnostic Table
| Symptom | Likely Cause | Check |
|---|---|---|
| File size remains high after SVGO | Optimization opportunities that only appear after a prior pass (e.g., unused IDs revealed after removing empty groups) | Run SVGO with --verbose and note the number of passes reported |
Nested <g> elements persist | Plugins like removeUnknownsAndDefaults or collapseGroups need a clean DOM before they can act on deeper levels | Inspect the SVG after a single pass; look for groups that contain only a single child |
| Build time spikes when enabling multipass | Very large SVGs cause many iterations before convergence | Measure total SVGO execution time with and without multipass: true |
Ordered Diagnostic Checks
Verify the current SVGO configuration. Look for a
multipasskey in your config file (JSON, JS, or CLI). If it is absent or set tofalse, the tool stops after one pass.Run SVGO on a representative SVG with verbose output:
# Run in your project root, assuming you have svgo installed locally npx svgo --verbose input.svg -o output.svgObserve the lines that start with
Pass. If you see onlyPass 1and a message likeNo changes detected, the process halted after a single iteration.Compare file sizes:
- Single‑pass output:
ls -lh output.svg - Multipass output (temporarily enable):
npx svgo --multipass --verbose input.svg -o output-multi.svg - Note the size difference; a reduction indicates further optimizations are possible.
- Single‑pass output:
Inspect the DOM for redundant groups. Using a quick grep:
grep -c '<g>' output.svg # count of opening g tagsIf the count is higher than in the multipass output, groups remain that could be collapsed.
Check for visual regressions (optional but recommended):
- Open both SVGs in a browser or SVG viewer.
- Toggle between them to ensure paths, fills, and strokes appear identical.
Fixes Tied to Findings
Enable Multipass in Configuration
If the diagnostic shows that a second pass yields a smaller file and no visual change, adjust your SVGO config to iterate until convergence.
JSON config (e.g., svgo.config.js):
module.exports = {
multipass: true, // <-- key addition
plugins: [
{ name: 'preset-default' },
// optional: fine‑tune plugins that benefit from multiple passes
{ name: 'removeUnknownsAndDefaults', params: { keepRole: true } },
{ name: 'collapseGroups' }
]
};
CLI one‑off (useful for ad‑hoc checks):
npx svgo --multipass input.svg -o output.svg
Limit Multipass Iterations (Optional Guard)
If build time becomes a concern, you can cap the number of passes. SVGO does not expose a direct max‑pass flag, but you can wrap the call in a script that runs SVGO a fixed number of times and stops when the output stops changing.
Example Bash guard:
#!/usr/bin/env bash
INPUT="input.svg"
OUTPUT="output.svg"
PREV=""
for i in {1..5}; do
npx svgo --multipass=false "$INPUT" -o "$OUTPUT"
if cmp -s "$INPUT" "$OUTPUT"; then
echo "Converged after $i pass(es)"
break
fi
cp "$OUTPUT" "$INPUT"
done
This limits the process to five iterations while still allowing early exit when no further change occurs.
Plugin‑Specific Tuning
Sometimes a single plugin blocks further optimization. For instance, removeUnusedNS may preserve a namespace that later prevents removeUnknownsAndDefaults from cleaning attributes. In such cases:
- Disable the blocking plugin temporarily and see if multipass yields a gain.
- If gain appears, consider adjusting its parameters or moving it later in the plugin list.
When to Escalate
- File size reduction after enabling multipass is negligible (<1 %) but build time increases dramatically (>30 % of total asset pipeline).
- Visual differences appear after multipass (e.g., slight shifts in path coordinates) despite using default plugin tolerances.
- The SVG source is generated by a tool that produces extremely deep nesting (>100 levels) and multipass loops exceed 20 iterations without converging.
In these scenarios, consider:
- Running SVGO with a custom
pluginsarray that excludes the most aggressive passes (e.g., disablemergePathsif it causes visual drift). - Applying a preprocessing step (such as
svgo --disable=collapseGroups) to flatten the SVG before multipass, then re‑applying selective optimizations. - Investigating whether the SVG can be simplified at the source (export settings in Illustrator/Inkscape) to reduce the need for heavy post‑processing.
Practical verification: After applying any of the fixes, repeat the ordered diagnostic checks. Confirm that the verbose log shows multiple passes, that the final file size is smaller than the single‑pass baseline, and that a visual diff reports no changes. If the build time increase is acceptable and the size gain meets your project’s thresholds, the change can be considered successful.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.