Google vs optimised

Optimising SVGs for Web Use — Part 2

Andreas Larsen
Dec 28, 2015 · 6 min read

If you haven’t then I’d suggest reading part 1 first. In this part 2 I’ll be showing you an example on how to optimise svgs for web use. I’ve explored a couple of other techniques since writing this and you can read about those in part 2½.

I’ve optimised some of the most commonly used social icons, badges and flags here: github.com/larsenwork/web.svg.min

Step 1 — get/draw an icon

Google Material Design icons are already quite optimised but I like a challenge so let’s try taking it even further.

This is what the downloaded svg looks like:

<svg fill=”#000000" height=”24" viewBox=”0 0 24 24" width=”24" xmlns=”http://www.w3.org/2000/svg">
<path d=”M0 0h24v24H0z” fill=”none”/>
<circle cx=”12" cy=”4" r=”2"/>
<path d=”M19 13v-2c-1.54.02–3.09-.75–4.07–1.83l-1.29–1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3–1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0–1.1-.9–2–2–2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16–1.52 2–2.83 2–1.66 0–3–1.34–3–3 0–1.31.84–2.41 2–2.83V12.1c-2.28.46–4 2.48–4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44–1.72 4.9–4h-2.07z”/>
</svg>

The transparent path covering the entire viewbox is only needed if you want the entire svg to be toggle-able. When I need a toggle-able svg it’s almost always inside an <a> element that I can use instead so I tend to remove those transparent paths.

Step 2 — determine the optimal size for the viewbox

What you want is a grid that is just big enough that your integers don’t distort your shapes.

This takes some experimenting but you almost always need it to be bigger than the supplied one for when you round all values to integers. Since Material Design icons are drawn over a grid it would be foolish to increase the viewbox size to e.g. “0 0 100 100”. Instead we’ll multiply the current grid by 4 to ”0 0 96 96".

Step 3 to 5

I’ve screen recorded the FontForge steps since it’s an editor many aren’t familiar with.

Step 3 — load the svg into your editor

Double click on a glyph and press command+shift+i to import the svg to both the Back and Fore layer.

Step 4 — reduce the number of nodes + handles

Step 5 — round to int

After the rounding you might need to make some adjustments to get a better path fit when comparing to the unmodified Back layer.

When satisfied: Choose “File”, “Export”.

Step 6 — re-add the circle

Step 7 — cleanup

<?xml version=”1.0" standalone=”no”?><!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width=”100%” height=”100%” viewBox=”0 0 96 96" version=”1.1" xmlns=”http://www.w3.org/2000/svg" xmlns:xlink=”http://www.w3.org/1999/xlink" xml:space=”preserve” style=”fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;”><path d=”M76,52c0,0 -11,1 -20,-8l0,14l12,0c5,0 8,4 8,8l0,22l-8,0l0,-20l-20,0c-5,0 -8,-4 -8,-8l0,-24c0,-8 10,-11 15,-5l5,6c7,8 16,7 16,7l0,8ZM51,72l8,0c0,0 -2,16 -19,16c-11,0 -20,-9 -20,-20c0,-16 16,-19 16,-19l0,8c0,0 -8,3 -8,11c0,7 5,12 12,12c9,0 11,-8 11,-8Z” style=”fill:#000;fill-rule:nonzero;”/><circle cx=”48" cy=”16" r=”8" style=”fill:#000;”/></svg>
Atom with live svg preview

Tools like svgo will get you 90% of the way but I tend to just open the svg in Atom with live svg preview and then removing excess information manually.

The Result

I’ve removed some unneeded commas + spaces after publishing this taking it from 332 to 304 bytes.

Before:  576 bytes 
After : 304 bytes
Saved : 47.2%
BEFORE<svg fill=”#000000" height=”24" viewBox=”0 0 24 24" width=”24" xmlns=”http://www.w3.org/2000/svg">
<path d=”M0 0h24v24H0z” fill=”none”/>
<circle cx=”12" cy=”4" r=”2"/>
<path d=”M19 13v-2c-1.54.02–3.09-.75–4.07–1.83l-1.29–1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3–1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0–1.1-.9–2–2–2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16–1.52 2–2.83 2–1.66 0–3–1.34–3–3 0–1.31.84–2.41 2–2.83V12.1c-2.28.46–4 2.48–4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44–1.72 4.9–4h-2.07z”/>
</svg>
AFTER<svg viewBox=”0 0 96 96">
<circle cx=”48" cy=”16" r=”8"/>
<path d=”M76 52c0 0–11 1–20–8l0 14l12 0c5 0 8 4 8 8l0 22l-8 0l0–20l-20 0c-5 0–8–4–8–8l0–24c0–8 10–11 15–5l5 6c7 8 16 7 16 7l0 8ZM51 72l8 0c0 0–2 16–19 16c-11 0–20–9–20–20c0–16 16–19 16–19l0 8c0 0–8 3–8 11c0 7 5 12 12 12c9 0 11–8 11–8Z”/>
</svg>

Note that I’ve also removed size+fill so remember to set those in your CSS. The xmlns attribute isn’t needed for inline svg.

Before vs after

Another example

Before: 1173 bytes
After : 291 bytes
Saved : 75.2 %
<?xml version=”1.0" encoding=”utf-8"?><!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.0//EN” “http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg version=”1.0" xmlns=”http://www.w3.org/2000/svg" xmlns:xlink=”http://www.w3.org/1999/xlink" x=”0px” y=”0px” viewBox=”0 0 87.22 100" enable-background=”new 0 0 87.22 100" xml:space=”preserve”><path fill-rule=”evenodd” clip-rule=”evenodd” d=”M83.624,75.961l-8.729,3.923L62.653,52.71l-1.188–2.625l-2.874,0.039L32.136,50.5
l-0.243–5.646h21.926v-8.781H31.531l-0.77–18.234c3.295–1.436,5.602–4.716,5.602–8.534C36.364,4.16,32.194,0,27.056,0
c-5.148,0–9.312,4.16–9.312,9.305c0,3.25,1.675,6.113,4.201,7.767l1.604,38.063l0.171,4.263l4.271–0.058l27.842–0.395l12.862,28.526
l1.803,3.999l3.988–1.789l12.733–5.717L83.624,75.961L83.624,75.961L83.624,75.961z”></path><path fill-rule=”evenodd” clip-rule=”evenodd” d=”M56.361,73.589l-1.18–0.279c-2.579,10.545–11.988,17.91–22.86,17.91
c-12.984,0–23.542–10.555–23.542–23.534c0–7.993,4.007–15.276,10.568–19.615l-1.112–7.623l-0.77–1.477C6.69,44.55,0,55.551,0,67.686
C0,85.499,14.5,100,32.321,100c12.268,0,23.156–6.833,28.63–17.32L56.361,73.589L56.361,73.589L56.361,73.589z”></path></svg>
<svg viewBox=”0 0 200 200"><path d=”M113 147l9 18c-11 21–32 35–57 35–36 0–65–29–65–65 0–24 13–46 35–57l1 3 2 16c-12 9–20 22–20 38 0 26 21 47 47 47 22 0 40–15 45–36zm54 5l7 16–33 15–29–65–65 1–3–84c-5–3–9–10–9–16C35 9 43 0 54 0s19 9 19 19c0 6–4 14–11 17l1 36h45v18H64v11l59–1 27 60z”/></svg>
Before vs after

PS

Larsenwork

Articles on web and type design+development

Larsenwork

Articles on web and type design+development

Andreas Larsen

Written by

Jack of all trades — master of some. Design+Code+Type+DIY. Meetup organizer.

Larsenwork

Articles on web and type design+development