Skip to content

Benchmarks

Noah Baldwin edited this page Jul 28, 2026 · 30 revisions

OXVG aims to be competitive in the following areas.

  • Correctness
  • Compression
  • Performance
  • Distribution

SVG Optimisation

When running SVGO's defaults against OXVG's defaults -- which are almost identical -- OXVG runs considerably faster.

Correctness

Maintaining correctness of SVG documents is important in ensuring OXVG is safe to use for a broad variety of use-cases. We offer two presets for safely optimizing SVGs

  • default: Is similar to SVGO's defaults and is safe to use for most SVGs using well-supported features
  • safe: Is the same as default, but has additional prechecks similar to svgcleaner
---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Broken files in W3C SVG 1.1 TestSuite"
    x-axis [SVGO, SVGCleaner, "OXVG (default)", "OXVG (safe)"]
    y-axis "Files (#)" 0 --> 1139
    bar [15, 3, 3, 2]
Loading
---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Broken files in Oxygen icon theme"
    x-axis [SVGO, SVGCleaner, OXVG]
    y-axis "Files (#)" 0 --> 5093
    bar [59, 0, 0]
Loading

How to run tests

Follow the instructions in the readme of packages/correctness/. In that directory you can set up the optimised files with the following command

cargo run optimise -r -. -o optimised/w3c w3c/svg

Compression

---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Output size (MB) of W3C SVG 1.1 TestSuite"
    x-axis [Original, SVGO, SVGCleaner, OXVG]
    y-axis "Total size (MB)" 0 --> 10
    bar [10, 5.8, 6.9, 5.2]
Loading
---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Output size (MB) of Oxygen icon theme"
    x-axis [Original, SVGO, SVGCleaner, OXVG]
    y-axis "Total size (MB)" 0 --> 1200
    bar [1200, 511, 504, 509]
Loading

Performance

---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Average cleaning time (ms) in W3C SVG 1.1 TestSuite"
    x-axis ["SVGO 4.0.0 (Node)", "SVGO 4.0.0 (Bun)", "SVGCleaner 0.9.6", OXVG]
    y-axis "Time (ms)" 0 --> 6
    bar [6.0, 4.9, 2.5, 0.2]
Loading
---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Average cleaning time (ms) in Oxygen icon theme"
    x-axis ["SVGO 4.0.0 (Node)", "SVGO 4.0.0 (Bun)", "SVGCleaner 0.9.6", OXVG]
    y-axis "Time (ms)" 0 --> 200
    bar [196.5, 160.0, 5.5, 3.7]
Loading
How it's run
# NOTE: There are 1139 w3c files and 5093 oxygen files
timeit { ./target/release/oxvg optimise -r -. -o w3c-optimised w3c } | $in / 1139
glob w3c/**/*.svg | timeit { par-each { ./target/release/svgcleaner $in $"(mktemp).svg" } } | $in / 1139
timeit { node ./bin/svgo.js -f w3c -r -o w3c-optimised } | $in / 1139
timeit { bun ./bin/svgo.js -f w3c -r -o w3c-optimised } | $in / 1139

# Output directory measured with `dust`
dust w3c-optimised -t

You may notice this produces SVGO results that look proportionally different to svgcleaner's. I believe this may be because their tests launch a separate Node process for each file, whereas ours is a lot fairer to how SVGO would realistically be used; by using the -f and -r flags.

Timings may differ machine to machine, so consider testing on your own device before committing to a decision!

These results are not statistically pure; they are based off a single run of the commands specified above.

SVG to JSX transormation

When running against SVGR's defaults, OXVG is also considerably faster. Alongside that I couldn't get SVGR to successfully process the w3c suite.

---
config:
    xyChart:
        width: 622
        height: 181
        showDataLabel: true

---
xychart horizontal
    title "Average build time (ms) in Oxygen icon theme"
    x-axis [svgr, "svgr --no-svgo", "oxvg jsx", "oxvg jsx --no-oxvg"]
    y-axis "Files (#)" 0 --> 163
    bar [154.3, 162.4, 3.4, 2.2]
Loading
How it's run
timeit { node ./svgr/packages/cli/bin/svgr --out-dir ~/Projects/oxygen-jsx -- oxygen }
timeit { ./oxvg/target/release/oxvg jsx --no-warn -r -o ~/Projects/oxygen-jsx/ ./oxygen/ }

Distribution

Distribution competes primarily in portability and size. By being portable, OXVG can be useful for people in as many environments as possible. By being small, OXVG can be cheaper to include as a dependency.

Program Portability Size (Binary) Size (Node) Size (Web/WASM)
OXVG Binary, Cargo, Node, Wasm 19.8MB 11.5MB 17.8MB
svg-cleaner Binary, Cargo 1.7MB N/A N/A
SVGO Node, Web N/A 1.45MB 0.8MB

As you can see, OXVG is currently ahead in portability but far behind in size. As OXVG matures we'll explore ways to shrink the build size and hopefully get ahead of the others. For now though, we're keeping size in mind, but focusing on making OXVG useful.

Clone this wiki locally