
Minify Your SVGs - vzhou842
https://victorzhou.com/blog/minify-svgs/
======
sheetjs
Unfortunately the reference to the actual minifier, SVGO
([https://github.com/svg/svgo](https://github.com/svg/svgo)), is buried in the
middle of the post.

SVGO is an incredible project driven by a single volunteer in spare time
(originally Kir Belevich
[https://twitter.com/deepsweet](https://twitter.com/deepsweet) , and for the
last few years Lev Solntsev
[https://twitter.com/ruGreLI](https://twitter.com/ruGreLI)). It's the type of
project you probably use regularly behind another tool like Sketch or SVGOMG
([https://jakearchibald.github.io/svgomg/](https://jakearchibald.github.io/svgomg/)).
They accept donations
([https://www.paypal.me/deepsweet](https://www.paypal.me/deepsweet)) and you
should definitely consider contributing if you find it useful.

~~~
est31
Another svg optimizer (link contains comparison to svgo):
[https://github.com/RazrFalcon/svgcleaner](https://github.com/RazrFalcon/svgcleaner)

------
social_quotient
Pro tip for people with SVGs that have an image inside. You can pull that
base64 image out of the svg, convert to image, compress it (tinypng, pngcrush
etc) then convert back to base64 and out back in the SVG. We automated this
with a slackbot but it’s often overlooked with all SVG optimization scripts.

~~~
mhe
Somewhat related: a while ago realized that the SVGs that draw.io generates
(exports) have an interesting property. If you include an SVG inside such a
drawing and you export it to SVG, that SVG is actually embedded as base64.
This is unfortunately not supported by some programs (e.g., Microsoft Office).
A quick fix is to actually expand the SVG into the big SVG. I wrote a quick
tool for this that does this for you (I should consider open sourcing this
maybe). Anyway, I bet doing this and then minimizing the SVG could result in
more savings?

~~~
social_quotient
Interesting. Care to share one of these images? I’d love to check it out.

------
v33ra
Related:
[https://jakearchibald.github.io/svgomg/](https://jakearchibald.github.io/svgomg/)

~~~
pier25
I use it every time I'm using SVG for the web.

My only problem is that when pasting SVG directly from Illustrator it finds an
invalid character at the end and refuses to use it. I have to paste the SVG
into an editor, remove some invisible character at the end, and then paste to
svgomg.

I reported this and offered to PR but never got an answer:
[https://github.com/jakearchibald/svgomg/issues/145](https://github.com/jakearchibald/svgomg/issues/145)

~~~
saagarjha
Is it legal to have a NUL byte in an SVG? Might want to also contact
Illustrator as well if it's not.

~~~
pier25
I doubt it, but I also doubt Adobe would pay attention...

------
discreditable
Be aware that svgo is a lossy operation. One thing it does is round the digits
in numbers to a certain precision. When I last worked with it, it also did
some things I did not like such as mess with viewboxes. I found that it messed
up the sizing of SVGs embedded with <img> tags in certain browsers. It has
been a while since I used it though.

~~~
gregable
I was curious about this. It looks like it has numerous individual plugins
that provide the actual functionality. Do you know if some of the plugins are
lossless, while others lossy? It may be possible to pick and choose the
lossless ones.

~~~
discreditable
It has a boat load of plugins. I looked at a few and after puzzling over which
were default enabled and default disabled I decided I didn't want to use a
program with unsafe defaults.

~~~
gregable
That's fair.

------
spiralganglion
I absolutely love ImageOptim for manually optimizing SVGs, JPGs, PNGs, and
GIFs. It's a simple GUI that wraps some excellent compression libs (including
SVGO), which I find much faster to use for one-off image optimization than the
CLI. It does a clever job of trying multiple compressors and picking whichever
one creates the smallest file for each image. You can run it in a lossless or
lossy mode, and tune various compression options. It's free (gratis), OSS, and
runs on Mac, Windows, and Linux.

I make it a habit of running images through ImageOptim before sending them via
Messages or Slack, as a courtesy for people on slow connections.

[https://imageoptim.com](https://imageoptim.com) (by HN user pornel)

Bonus round: When it comes to optimizing SVGs, nothing beats hand-editing the
SVG source. I've done a fair bit of that optimizing the artwork for
[https://www.lunchboxsessions.com](https://www.lunchboxsessions.com) and it's
been totally worth the effort. Taking a detailed 10k SVG down to 500 bytes
with no perceptual difference is a huge win when you have hundreds of those
SVGs on the page and you serve people who still use dialup.

~~~
uxamanda
ImageOptim also strips out a lot of (all?) the image metadata which is often a
place people leak data unintentionally.

------
lwhsiao
Yet another alternative that has benchmarks against svgo and scour is
svgcleaner:
[https://github.com/RazrFalcon/svgcleaner](https://github.com/RazrFalcon/svgcleaner).

It is written in Rust and has been my go to for SVG optimization due to its
speed.

------
taeric
Would be more compelling with the sizes of that neutral net in the different
passes. As it is, this is like comparing two algorithms on a small dataset
without accounting for growth in data on behavior.

------
owenshen24
There's also [https://vecta.io/nano](https://vecta.io/nano), which I've found
to sometimes give better results than SVGOMG

------
jkoudys
A related (but less automated) advantage is if you're building react
components that render SVG, this minified output will be much shorter and
hopefully easier to reach through and figure out where you want to insert your
own colours/child components.

------
iamben
Illustrator has an export SVG function (as opposed to just saving as an SVG,
which I was doing and then using a minifer for a long time) that will minify
it for you.

That said, it currently appears unable to reopen those minified SVGs (go
figure).

~~~
pier25
FYI you can copy any vector in Illustrator and when you paste it somewhere it
is actually SVG code.

~~~
detritus
Which is why I fairly frequently end up with amusingly-long pastes of raw svg
markup being posted into email fields... .

------
burevestnik
I love seeing efforts to make software more efficient, so I enjoyed this post,
but at the same time your own blog has a 434kb 512x512 png favicon. I'm not at
all a web developer and so I don't know if there is a technical reason for
that, but it seems a bit absurd in juxtaposition to your goal to reduce a 2kb
svg to 100 bytes.

I've seen this on a number of other blogs, which seem to focus on minimal
design. Can anyone explain what the need is for these enormous favicons?

~~~
Nadya
512x512 is specifically for browser loading splash screens when the site is
added as a launcher on a phone. It's required for Chrome to have an "Add to
Home Screen" prompt and requires a 192x192 and 512x512 icon. I imagine most
minimalist sites you browse are expecting people to add the website as an
icon/app launcher on their phones. Not sure how common an experience that is
for users, I sure as hell wouldn't but maybe other people might.

Was intended for web apps I believe but is usable by sites that aren't web
apps.

Read more here: [https://developers.google.com/web/fundamentals/web-app-
manif...](https://developers.google.com/web/fundamentals/web-app-manifest/)

------
jchw
Don’t forget to also use GZip or another transport compression on them as
well. Text tends to compress well, and can net additional benefits on top of
minification.

~~~
jrockway
I ran the examples in the article through gzip. The long one is 789 bytes
compressed, and the short one is 266 bytes compressed.

The reality is that while text compresses well, gzip doesn't know what data is
relevant. It keeps it all. So for this example, the original long svg contains
things like inkscape configuration (the window height, the current layer name,
etc.) while the shorter one omits all that. So not emitting that information
will always be more efficient than emitting that information and compressing
it.

~~~
penagwin
He means in addition to minifying the SVG, you should compress it for
transport (which is likely happening already depending on how you serve it)

------
willis936
This is neat, but I wonder: are there path optimization tools? For instance:
flattening, removal of entirely occluded paths, and combination of paths.

~~~
notduncansmith
Not exactly that but comes close (and perhaps could be used for that if you
rasterized the input vector):
[https://vectormagic.com/](https://vectormagic.com/)

I haven’t used their desktop edition but on the web it worked really well for
cleaning up images. I imagine similar algorithms could be applied directly to
SVGs to simplify them.

Worth noting is the manual step in their workflow - I think there’s only so
much you can do before you need a human to decide whether any important
meaning has been lost.

------
willis936
SVG optimization seems like a good choice for delivery, but oftentimes I find
myself using SVG in a development context. Having human readable, annotated
SVG files is useful when looking through previous revisions. In terms of
compressed filesize: there's no serious practical gain.

~~~
lotyrin
It's analogous to JS minification -- Clients on the production site should get
a bare minimum and the VCS should have the readable form with all the digits
of precision and whatever comments, non-functional groups acting as layers in
the editing software, etc.

------
jgalt212
Aren't garden variety SVG files ~75% smaller than other lossless compression
methods (e.g. PNG). As such, is minification necessary or a best practice?

In short, is this an intellectual exercise or something that should be in an
SVG producer's toolkit?

~~~
chrismorgan
Raster formats have a worst-case file size that is linked to their visual
size.

SVG has no such limit; for a given visual size it can have arbitrarily many
objects. If you’re not careful, you can quite easily end up with multi-
megabytes SVGs where a PNG would have been <100KB.

SVG is therefore a dangerous format to use if you don’t know what you’re
doing, because its performance characteristics are quite unlike raster
formats.

------
mtlynch
This is an excellent post!

It does a fantastic job of defining the problem and walking the reader through
the process of solving it. The language is so succinct and clear that even if
the reader had never heard of SVGs before, they would understand this post.

Well done, Victor!

~~~
vzhou842
Thanks, appreciate that!

------
pcmaffey
Nice work, svgo is awesome. I'd love to adapt this to a non-gatsby post-build
tool that also runs image compression on any jpg/png files.

Big advantage to running post-build besides convenience is that sometimes
Inkscape doesn't render optimized svg's correctly. So I have to keep originals
elsewhere.

------
adityapatadia
We provide hosted service for optimising SVG. If anyone is interested for
image optimisation as a service, take a look here:
[https://www.gumlet.com](https://www.gumlet.com)

~~~
jarek-foksa
Just another shameless plug here. I'm developing an SVG editor which focuses
on generating clean and readable SVG files (e.g. no redundant namespaces,
metadata or deeply nested structures).

You can try it online on [https://boxy-svg.com](https://boxy-svg.com), there
are also desktop apps for macOS, Windows, Linux and Chrome OS.

------
ricardobeat
For inlining, you can even go further and remove that xmlns attribute to end
with something around 50 bytes. I'd recommend keeping the viewbox though,
since it's required for proper resizing.

------
kuschku
Most of the time, automated optimizers for SVG are relatively bad, though, and
rewriting the SVG by hand can get a 2KiB svgo result down to 200 bytes or
less.

------
frenchyatwork
Don't SVGs have to have an XML declaration? I think that magic will fail to
identify the content type of an SVG if it's not a valid XML file.

~~~
blihp
No, the declaration is optional in many cases.

------
bluepnume
Very neat! Now just need to figure out how to plug svgo into my jsx rendering
pipeline, at build time.

------
kazinator
I've also noticed the cruft in Inkscape SVG's.

The TXR logo SVG is cleaned with a TXR script:

[http://www.kylheku.com/cgit/txr/tree/win/cleansvg.txr](http://www.kylheku.com/cgit/txr/tree/win/cleansvg.txr)

The original looks like this:

[http://www.kylheku.com/cgit/txr/tree/win/txr.svg](http://www.kylheku.com/cgit/txr/tree/win/txr.svg)

The cleaned one is not in the repo. It's obtained by "txr cleansvg.txr
txr.svg":

    
    
      <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      
      <!-- TXR Logo
           Copyright ... -->
      
      <svg xmlns="http://www.w3.org/2000/svg"
           viewBox="0 0 277.4375 297.4375"
           id="svg2"
           version="1.1">
        <g transform="translate(-200.03125,-416.34375)">
          <g transform="matrix(3.078678,0,0,3.078678,-1110.4532,-1582.3752)">
            <path d="m 476.96875,651.28125 c -7.29171,7e-5 -14.03911,1.37247 -20.21875,4.125 -6.17972,2.75267 -11.36983,6.39069 -15.5625,10.875 -4.33856,4.5938 -7.66668,9.81776 -10,15.6875 -2.33334,5.86983 -3.50001,11.92191 -3.5,18.15625 -10e-6,7.29167 1.28645,13.62241 3.875,19 2.58853,5.3776 6.02082,9.89063 10.25,13.5 4.26559,3.60937 9.05205,6.29426 14.375,8.0625 5.32287,1.76822 10.74475,2.65623 16.25,2.65625 6.1614,-2e-5 11.73692,-0.987 16.75,-2.9375 5.01294,-1.95054 9.35409,-4.51564 13,-7.6875 l -1.71875,-2.78125 c -3.60945,2.98957 -7.66675,5.27603 -12.1875,6.84375 -4.5209,1.5677 -9.67194,2.34374 -15.46875,2.34375 -5.14067,-10e-6 -9.93234,-0.82814 -14.34375,-2.46875 -4.41149,-1.64064 -8.224,-4.09376 -11.46875,-7.375 -3.31773,-3.39062 -5.89586,-7.61198 -7.71875,-12.625 -1.82294,-5.013 -2.71877,-10.80728 -2.71875,-17.40625 -2e-5,-6.85413 1.16665,-13.00517 3.5,-18.4375 2.33331,-5.43223 5.36976,-9.94787 9.125,-13.59375 3.86454,-3.75515 8.14059,-6.59889 12.84375,-8.53125 4.70307,-1.93222 9.54162,-2.90618 14.5,-2.90625 5.21348,7e-5 9.82806,0.80215 13.875,2.40625 4.04679,1.60423 7.40096,3.79174 10.0625,6.5625 2.77074,2.80735 4.83846,6.02349 6.1875,9.6875 1.34887,3.6641 2.03116,7.66672 2.03125,11.96875 -0.1377,8.31795 -2.4429,16.899 -11.71184,23.81796 -4.24484,3.16863 -9.29313,4.01343 -14.18104,4.49201 -2.5623,0.25088 -7.11725,0.30793 -9.74156,0.25794 -1.81112,-0.0345 -3.02482,-0.27866 -3.74043,-0.81795 -0.71564,-0.53929 -1.06251,-1.22605 -1.0625,-2.0625 -1e-5,-0.90247 0.57819,-3.28219 1.71875,-7.15625 l 7.90625,-28.15625 3.59375,0 c 3.15321,4e-5 5.11461,0.28996 5.875,0.90625 1.00632,0.81447 1.49996,2.04944 1.5,3.65625 -4e-5,1.36476 -0.20014,2.91736 -0.625,4.65625 l 2.78622,0 4.09375,-13.875 -37.14277,0 -3.53125,13.87504 2.29405,0 c 0.62617,-2.3112 1.42225,-4.1203 2.40625,-5.375 0.98398,-1.25462 2.27599,-2.21462 3.875,-2.875 1.59897,-0.66031 3.69596,-0.96871 6.3125,-0.96875 l 2.71875,0 -8.34375,29.125 c -0.93928,3.16968 -1.69323,5.23924 -2.21875,6.21875 -0.52556,0.97952 -1.10147,1.65706 -1.75,2.03125 -0.93928,0.55029 -2.28692,0.8125 -4.03125,0.8125 l -0.875,0 -0.96875,3.46875 19.90942,0.12627 c 4.65825,0.0295 14.28759,-0.73275 17.58443,-1.82102 6.80584,-2.24657 10.97411,-5.63785 13.61133,-8.47036 1.87071,-2.00924 7.5173,-9.18725 7.82441,-20.78032 0.12261,-4.62853 0.078,-9.57025 -1.39847,-13.83592 -1.47666,-4.26557 -3.67197,-8.03119 -6.625,-11.3125 -2.95321,-3.31763 -6.74488,-6.00774 -11.375,-8.03125 -4.63028,-2.02336 -10.09903,-3.03118 -16.40625,-3.03125 z"/>
          </g>
        </g>
      </svg>

~~~
makapuf
Are you talking about inkscape SVG which also save many details for inkscape
or raw/small svg saved by inkscape ? Those if needed could use a patch if
theyre too big and there are low hanging fruits

------
orisho
Why? Why minify everything? It all gets gzipped at the HTTP layer anyway! I
truly cannot understand this need to minify everything (JS included)

~~~
basilgohar
I started by downvoting your comment, and I realized I was choosing the
cowardly way of reacting. I am saying this just to illustrate my own shallow
reading of your comment at first and how I was avoiding actually being
helpful.

The short answer is that 99% of the time no purpose is being served by that
cruft except to be bloat. Minifiers remove that cruft and optimize for the
intended audience, which is machines.

The longer answer is that in optimizing for machines, you're also optimizing
for humans in the long run. Anyone stuck with a 2G connection, dial-up, or
Bluetooth tethered device, or a new ultra low powered device on a different
CPU architecture, will appreciate not having to operate solely in the world of
gigabit+ connections, 8GB mobile devices, or 8 core hyperfast CPUs. Realize
that such use cases still exist, and for very legitimate, not truly edge
cases.

Think of pages with hundreds or thousands of vector images. Not everyone can
afford to run a Blink-powered browser or have CPU cycles for days. Every
little bit helps.

Edit to fix typo and add further clarity.

------
qwerty456127
In general I'd recommend the opposite: don't minify anything unless necessary,
prettify it instead. Every plaintext-based format file should be optimized for
human readability unless you actually need to make it hard to read (e.g. you
are developing a proprietary product not meant to be open-source) or your
bandwidth is limited so severely that every single byte matters.

Nevertheless the kind of minification demonstrated in the example (removing
Inkscape bloat) feels really great and actually makes the file more human-
readable. This reminds me of HTML files generated by MS Word and other WYSIWG
editors which included tons of bloat code that actually harmed rendering
(needless to say human readability).

~~~
crazygringo
I completely disagree. It's trivial enough to run any minified file through a
prettifier.

Even in the first world, on a spotty mobile connection every single byte
matters, and _some_ of your users are almost _always_ going to be in that
situation some of the time.

Think of minifying as "compiling" for the web. A good dev makes their site
performant, and doesn't care about generating readable source code for end-
users which 99.9% of them don't care about.

If you want to expose the site's source code to the world in a readable
format, then just publish it on GitHub as well, which is the audience that
might actually care.

Readable plaintext files are for developers on your team. Not for end users of
your product.

