Optimizing SVG for the Web

So you have an amazing vector and you’re about ready to send it out for the world to see, but you notice it’s XML (the stuff that makes up an SVG) is a bit bulky. We’ll take a look at a command line tool that can help us clean that up a bit called SVGO. It’s a Node based, open-source (free) project hosted on GitHub that helps cleanse verbose SVG files and output a well optimized one.


Installation

I use SVGO religiously making it my favorite out of all the tools available. There’s a GUI version of SVGO, but I suggest you stick to the command line tool. Installation is dead simple using NPM:


npm install -g svgo

This command will install SVGO globally in your system so you can use it anywhere you want no matter the directory you’re in. Now that you have SVGO installed you can run the following command to cleanse your very first SVG!


svgo path/to/my-awesome.svg

Optimizing

To demonstrate SVGO I’m going to download an SVG directly from one of my favs The Noun Project. I can see the SVG I downloaded is pretty small before optimization -965 bytes. The XML of the SVG currently looks like this…

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="close" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
  <line fill="none" stroke="#000000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" x1="49.942" y1="49.843" x2="34.896" y2="34.865"/>
  <line fill="none" stroke="#000000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" x1="49.942" y1="49.887" x2="64.896" y2="34.911"/>   
  <line fill="none" stroke="#000000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" x1="49.942" y1="49.887" x2="64.895" y2="64.865"/>   
  <line fill="none" stroke="#000000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" x1="49.942" y1="49.887" x2="34.99" y2="64.864"/>
</g>
<circle fill="none" stroke="#000000" stroke-width="8" stroke-miterlimit="10" cx="50" cy="49.917" r="39.833"/>
</svg>

Heading back to the command line I cd into my test directory and run svgo on the svg we looked at above:


svgo icon_79124.svg

Done in 57 ms!
0.942 KiB - 56.8% = 0.407 KiB

As you can see we saved quite a bit and now the SVG weighs in at 417 bytes and the XML looks like this!

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><g stroke="#000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" fill="none"><path d="M49.942 49.843L34.896 34.865M49.942 49.887L64.896 34.91M49.942 49.887l14.953 14.978M49.942 49.887L34.99 64.864"/></g><circle stroke="#000" stroke-width="8" stroke-miterlimit="10" cx="50" cy="49.917" r="39.833" fill="none"/></svg>

You might be saying to yourself “Ok that’s cool, but what else you got?”

Well, we can pass some flags to svgo. For example, if we want the XML to be pretty printed after we optimize we can do that like so…


svgo --pretty icon_79124.svg

Done in 55 ms!
0.942 KiB - 54.1% = 0.433 KiB

The XML will now be indented and stacked nice, nice for us without minifying the entire guts of the SVG as you can see:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
    <g stroke="#000" stroke-width="8" stroke-linecap="round" stroke-miterlimit="10" fill="none">
        <path d="M49.942 49.843L34.896 34.865M49.942 49.887L64.896 34.91M49.942 49.887l14.953 14.978M49.942 49.887L34.99 64.864"/>
    </g>
    <circle stroke="#000" stroke-width="8" stroke-miterlimit="10" cx="50" cy="49.917" r="39.833" fill="none"/>
</svg>

Notice we still shaved the file size too! The SVG went from 965 bytes down to 443 bytes! Someone give me a high five already! [cricket sounds]

We can also take base64 and convert it to an SVG along with the ability to rename the output file to anything we want! Holy smokes someone pinch me!


svgo -s 'data:image/svg+xml;base64,........' -o base64.min.svg

Hold on to your hats buckaroos because SVGO can convert to base64 as well! To convert an SVG to base64 you can run the command that follows:


svgo icon_8260.svg --datauri=base64

Done in 51 ms!
1.258 KiB + 35.2% = 1.701 KiB

WARNING: This will overwrite the XML of your SVG and replace w/base64.

If you desire to enable plugins that are turned off by default it’s as simple as passing a flag to your command. For example, If you wanted to optimize your svg and also remove the viewbox attribute during optimization that would look like so…


svgo path/to/image.svg --enable=removeViewBox

If you wanted to pass multiple plugins to your --enable flag you can do that like this…


$ svgo path/to/image.svg --enable='removeViewBox,removeComments,removeUselessStrokeAndFill'

For those still wondering if SVGO can optimize an entire folder the answer is yes, but the command listed on the README.md is currently broken. Fortunately someone came to the rescue in the issue tracker and suggested, based on a recent commit by a generous soul, to use this approach for now in order to optimize entire SVG folders…


$ svgo -f <input_folder> -o <output_folder>

Additional Tips

If you want to convert your SVG to base64 without SVGO you could do the following from your command line…

openssl base64 < path/to/image.svg

convert file


$ openssl base64 < path/to/image.svg | tr -d 'n' | pbcopy

don’t convert entire file contents. just copy the base64 output to your clipboard

“OK, I see the base64 code pasted from my clipboard, but it’s still missing something?” Yup! In order to display a base64 you need the following in front of your base64 output…


data:image/svg+xml;base64,.....base64-clipboard-output-goes-here........

“Alright, but how do I get openssl installed?” You’re in luck because you can install it with Brew. For those unfamiliar with Brew, it’s a really great package manager for Mac. I won’t go into an in depth discussion about Brew, but I highly suggest you do if it’s not already installed.

Do you have suggestions, tips, feedback for a perfect SVG optimization workflow? Leave a comment and let us know!


Notes

  1. Always make sure to unite and simplify paths plus outlining text before you save as an SVG.
  2. Enabling and Disabling SVGO plugins is a bit confusing. Remember SVGO plugins are the name’s of their JS files listed here : https://github.com/svg/svgo/tree/master/plugins

Resources

Other Tools

Want to become a better web developer?

Join over 25,000 other developer & designers who get awesome links to the best news and articles each week delivered directly to their inbox.

Dennis Gaebel

Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.

5 Comments

  1. Works perfectly but i don’t understand the relationship between openssl and svgo ?

    • openssl is another tool you can use if you don’t want to use SVGO. You can install openssl with brew which is a package manager for Mac.

  2. Great tutorial thank you dennis.

    • NP! Glad it was of help. Happy optimizing!

  3. Thanks, for the write-up. I just used svgo on a file that had already been optimized (with this tool: http://petercollingridge.appspot.com/svg-editor) and it further reduced the size by 27%. Nice! Using both tools yielded a smaller file than either did on it’s own.

    It might be worth mentioning that svgo overwrites the target svg file, using the syntax shown here. Use `svgo test.svg test.min.svg` to preserve the original.

This post currently has 5 responses. What do you think?

You can use basic HTML when posting code, please turn all < characters into &lt; or > into &gt;
If the code is multi-line, use <pre><code></code></pre>

Leave a Reply

Your email address will not be published. Required fields are marked *