tooling.report

feature

Compress SVG

Can SVGs be optimized automatically?

Person in shorts with blue hair walking left

Introduction

It's become relatively common to "import" SVG files from JavaScript, either to obtain a generated asset URL for the SVG or to inline its contents as a string. In both cases, it's important to be able to process imported SVG assets to minimize their network or bundle size impact.

The Test

This test builds an application consisting of a JavaScript module that imports an SVG image. Each build tool is configured to pass the SVG though an optimization step, generally SVGO.

index.js

import svgUrl from './vector.svg';
console.log(svgUrl);

vector.svg

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  viewBox="0 0 1000 1000"
>
  <text x="50" y="50">Ohai</text>
</svg>

The build result should be a JavaScript bundle created from index.js, where svgUrl is now the generated URL for vector.svg. The SVG should be optimized, which should produce a version with whitespace and unnecessary attributes removed:

<svg xmlns="http://www.w3.org/2000/svg"><text x="50" y="50">Ohai</text></svg>

Conclusion

browserify

Using the gulp-svgmin plugin, SVGs can be minified using SVGO.

parcel

With the @parcel/transformer-svgo, Parcel will minify SVGs. The reason this test is a "partial" pass is because the plugin is undocumented.

Issues

rollup

Rollup's generateBundle hook gives you full access to build details before files are written. A small plugin can be written to transform the contents of the build.

webpack

Webpack doesn't include any compression or asset optimization by default, but there are numerous plugins and loaders available for doing so. Imported SVG assets can be compressed using svgo-loader, which combines with file-loader to allow importing an SVG and getting its compressed hashed asset URL.