Official vs optimised

Optimising SVGs for Web Use — Part 1

In this article I’ll cover the basic concepts of svg path optimisation. Part 2 and part 2½ is where I’m showing you how I’m doing it.

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


Raison d’être

IE8 use where I live is 0.35% 🤗

Why use svg in the first place? Because IE8 is gone and svgs are awesome and should replace icon fonts — explained brilliantly here: https://css-tricks.com/icon-fonts-vs-svg/

Why care about optimising them? Pure graphic designers care only about how their drawing looks. This was sufficient when graphics were printed out or rasterised into pngs. But using vector graphics every extra node, handle, decimal point and superfluous meta information adds to the total vector file size.

Why care about e.g. 635 bytes? When you aren’t optimising svg’s they still aren’t that big compared to rasterised graphics but as soon as you are using just a couple of icons on your page it all adds up and every byte and millisecond counts.

Also, you’ll sleep better at night knowing your website is flying as fast as possible.

NB

I’ll only be talking about optimising the actual drawing but do note that you can shave of a lot of excess meta information too — svgo is great for this (available as apps, tasks, folder action, etc…).

This is all that’s needed do draw a small square when inlining svg:<svg viewbox=”0 0 3 3">
<path d=”M1 1 l1 0 l0 1l-1 0z”/>
</svg>

If you’re repeatedly inlining the same SVG in one document you’re doing it wrong. Use svg sprites — this 3 min Medium read explains why and how.


The Path

A vector path is drawn over a grid using nodes with optional handles (for those sexy curves). Learn more about them on developer.mozilla.org

There are multiple ways to reduce how much code is needed to draw a path:


Way too many nodes in the CodePen logo

Use fewer nodes

Clean up your curves before exporting. This is especially important if you’ve been tracing. CodePen has forgotten to do this.

(Edit: it has now been fixed)


Use fewer handles

You can sometimes draw an almost identical curve using only one handle instead of two.

TWO HANDLES
<path d=”M1 5c2.331–2.167 4.998–2.167 8 0/>
ONE HANDLE
<path d=”M1 5c3.736–3.629 8 0 8 0"/>

Use integers

It’s only a matter of having a big enough grid (called viewbox in SVG terminology) and you won’t be able to tell the difference. These look the same:

FLOATS
<path d=”M7.059,1.034l-4.033,1.933l-1.084,4.982l6.016,-0.899l-0.899,-6.016Z”/>
INTEGERS
<path d=”M7 1l-4 2l-1 5l6–1l-1–6Z”/>

Don’t use a grid that is any bigger than necessary

If your grid is big then so are your coordinate values. What you want is a grid that is just big enough that your integers don’t visibly distort your shapes. Exactly what size your grid needs to be depends on how complex your drawings are and what level of detail is needed.

BIG
<svg viewBox="0 0 1000 1000">
<path d="M700 100l-400 200-100 500 600-100-100-600z"/>
</svg>
SMALL
<svg viewBox="0 0 10 10">
<path d="M7 1l-4 2-1 5 6-1-1-6z"/>
</svg>

In Short

  1. Fewer nodes
  2. Fewer handles
  3. Use integers
  4. Grid: Big, but not too big.

The result

GRAPHICS

I’d say the differences are imperceptible — especially at sizes normally used for icons.

Official vs optimised
Official and optimised layer compared in detail and for the whole icon

CODE

OFFICIAL
<svg viewBox="0 0 274 223">
<path d="M273.39 27.123c-10.059 4.461-20.869 7.477-32.215 8.832 11.581-6.941 20.473-17.933 24.662-31.031-10.837 6.428-22.841 11.096-35.617 13.611-10.232-10.901-24.809-17.713-40.941-17.713-30.977 0-56.091 25.114-56.091 56.088 0 4.397.497 8.677 1.453 12.783-46.616-2.339-87.945-24.669-115.609-58.604-4.828 8.284-7.594 17.919-7.594 28.198 0 19.459 9.902 36.627 24.952 46.686-9.194-.291-17.843-2.815-25.405-7.016l-.005.705c0 27.176 19.334 49.847 44.993 54.998-4.707 1.282-9.662 1.967-14.777 1.967-3.614 0-7.128-.351-10.553-1.006 7.138 22.284 27.852 38.5 52.396 38.953-19.197 15.043-43.381 24.01-69.66 24.01-4.527 0-8.992-.265-13.379-.783 24.822 15.914 54.304 25.199 85.979 25.199 103.169 0 159.585-85.467 159.585-159.586 0-2.431-.054-4.85-.162-7.256 10.957-7.908 20.468-17.787 27.988-29.035z"/>
</svg>
OPTIMISED
<svg viewBox="0 0 800 800">
<path d="M679 239s-21 34-55 57c7 156-107 329-314 329-103 0-169-50-169-50s81 17 163-45c-83-5-103-77-103-77s23 6 50-2c-93-23-89-110-89-110s23 14 50 14c-84-65-34-148-34-148s76 107 228 116c-22-121 117-177 188-101 37-6 71-27 71-27s-12 41-49 61c30-2 63-17 63-17z"/>
</svg>