Optimiser - noahbald/oxvg GitHub Wiki

The optimiser feature of OXVG aims to be a native drop-in replacement to SVGO. It will take an SVG document and transform it to produce an SVG with a smaller file-size and more compressable content.

It has three main concerns it aims to best the competition in

  • Runtime performance: We want to be fast
  • Correctness: We don't want to visually change documents
  • Usability: We want to be portable, familiar, and simple

Usage

[!TIP] You can try out OXVG right in your browser using OXVGUI, a simple web-based playground built by Jonas Geiler (@jonasgeiler).

If you're coming from SVGO, using OXVG should be familiar. However, in an effort to be safer and simpler to use OXVG by default works under the following constraint.

  • Do one thing well (i.e. the Unix Philosophy)
  • Dry-run by default (i.e. do nothing by default)

So the best way to run it is as follows

cat my-file.svg | oxvg optimise > my-file.optimised.svg

In this way, oxvg only does one thing (optimises the file) without doing anything (reading/writing is handled by cat and >)

Luckily, we do provide some shortcuts for your ease of use.

# Read and optimise file to stdout
oxvg optimise my-file.svg

# Read and optimise many files to stdout
oxvg optimise svgs/

# Read and optimise many files and directories to stdout
oxvg optimise svgs/ -r

# Read and optimise many files and directories back to input files
oxvg optimise svgs/ -r -o

# Read and optimise many files and directories to a new location
oxvg optimise svgs/ -r -o output/

# Read and optimise many files and directories to a new location, including hidden files
oxvg optimise svgs/ -r -o output/ -.

SVGO Parity

There are some differences to SVGO driven both by the limitation and advantages of writing such a library natively. Some notable differences are as follows.

Configuration

By using Serde to parse configuration files it has to fit a concrete structure. In order to have a configuration exactly the same as SVGO we would have to implement too many custom de-serializations.

  • Configuration Structure: To improve the simplicity of OXVG as a Rust program, the configuration structure is somewhat different. A utility is available in the napi and wasm packages to handle SVGO configs.

DOM parsing & serialization

SVGO uses a fork of sax and css-tree to parse SVG documents which are well-regarded libraries in the JavaScript ecosystem. These parsers break the document into an AST represented as an object tree of string values.

With OXVG we use our own SVG representation and LightningCss, which provides a rich representation of document values. This rich type system is partly what allow us to run faster and more extensive optimisations. Each type only needs to be parsed once and then they can apply their own granular optimisations upon themselves.

This means, at a general level, you may notice the following differences to SVGO

  • Attribute and CSS values may be minified despite turning off certain jobs/plugins.
  • CData sections will always be converted to text.
  • Optimisations are more correct, producing fewer broken documents.
  • XML namespaces are handled more effectively

Jobs/Plugins

Each plugin has it's differences documented in the optimiser docs

Alternatives

It's worth considering the following high-quality projects depending on your needs

  • SVGO: Which OXVG Optimiser is based upon
  • svgcleaner: A Rust-based lossless optimiser
  • scour: A Python-based optimiser similar to SVGO