DEV Community

Cover image for The smallest SVG
Ross Angus
Ross Angus

Posted on • Updated on

The smallest SVG

Since I started embedding SVGs directly into markup, I've become increasingly motivated to make them smaller. I've used SVGOMG and Nano both of which have taught me all kinds of tricks to shave embedded SVGs to a fraction of their former size.

But when you've been though all that and the icon is still half a screen of gibberish, where else is there to go?

The answer is, of course, that we need to look at how the SVGs are made.

If you've learned your craft as a pure web developer, you might have raised the occasional eyebrow at the behaviour of our sisters and brothers on the design side. Who can forget the enigmatically named "Layer 433" in that Photoshop document, for example? But these shortcuts mean nothing for the size of the final file size.

That's not the case for SVG. All those layers end up in the final file and there's only so much automated tools can do about it.

But that's not the end of it. Let's (unfairly) pick on one icon by Iconic from The Noun Project (a wonderful resource for SVGs). Here's what Iconic's chicken icon looks like, when we open it in Inkscape and examine the nodes which make up each path:

The nodes which make up the original chicken icon

Each of those nodes is basically a tiny fulcrum around which the line can curve or turn a sharp corner. But using the pen tool in Illustrator is hard. Sometimes it's easier to create a lot of small curves, rather than one single one.

Types of SVGs

Look, I don't know much about creating SVGs, so take this with a pinch of salt, but they come in two flavours:

  1. Big old shapes, which are filled in with colour (or black, if you don't specify one)
  2. Pointy or curvy lines, which you can only see when they get a stroke applied to them

Iconic's chicken is the first kind, even though it looks like the second kind. As it turns out I need it to be the second kind, because the lines are too thin. So I decided to redraw it from scratch, as a series of strokes over the original image.

Here's my strokes over the top of Iconic's chicken (note: I am aware of how disgusting this sounds, let's ignore it and move on):

Two chickens, one on top of the other

I've removed the shine from the original icon because it was freaking me out.

Here's the nodes which make up the stroke:

Nodes on the redrawn chicken, using strokes instead of fills

We've gone from I'm not sure how many nodes down to 11. Let's compare the compressed SVG code:

Original

Remember that this is a filled shape and the default fill is black, so there's no fill attribute.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" aria-label="Chicken">
  <path d="M76.5 33.3l-8.3-6.6 4-5c-1.3-2-1.3-4.7.1-6.6 3.4-3.8 8.7-2 10.2 2.2 4.5.7 7.5 5.4 4.4 9.4a5.7 5.7 0 01-6.4 1.6zM73 26.2l3 2.4 3.8-4.7c1.3 1 3.5 2 4.5.7 2.1-2.9-1.5-5.4-4.7-3.5 1.2-4.6-2.7-6.2-4.5-3.9-.7 2.2.2 3 1.7 4.2z"/>
  <path d="M54 72.3a19.1 19.1 0 01-19.2-17.8 21.4 21.4 0 014.7-15.2c3.5-4.3 8.4-7.1 13.7-8l3.1-.1c8.2-.9 12.9-5.5 13-5.6l1-1 8.2 6.5-1 1.3c-3.3 4-2.8 11.3-2.5 14.2a21.5 21.5 0 01-4.4 17.5 21.2 21.2 0 01-16.5 8.2zM70.6 29a27 27 0 01-14 5.5l-3 .2a18 18 0 00-11.3 6.7 18 18 0 00-4 12.8 16 16 0 0015.9 14.7c5.4 0 10.4-2.5 14-6.9A18 18 0 0072 49.4c0-.8-.2-1.6-.3-2.2-.5-4-.7-10.7 2.1-15.5z"/>
  <path d="M46 87C22.6 87 .5 87 .5 66.8c0-19 20.4-34.6 45.5-34.6 1.2 0 2.5 0 3.7.2 10.1.6 9.7-.1.5 3.2a18.3 18.3 0 00-12 18.6 16 16 0 0015.9 14.7c5.4 0 10.4-2.5 14-6.9A18 18 0 0072 49.4c-.6-4-.4-7.4-.2-11.3a35.8 35.8 0 0119.5 26A11.7 11.7 0 0187.8 87H46zm-2.8-51.3c-22 1-39.4 14.6-39.4 31 0 15.8 16 16.9 42.2 16.9h41.8c4.6 0 8.4-3.8 8.4-8.4-.4-4.8-3.2-7.7-8.1-8.4-.3-10.4-7.4-18.4-13.3-22.7.1 2 .5 4.3.7 6.1 0 5-1.6 10-4.8 14A21.2 21.2 0 0154 72.3a19.1 19.1 0 01-19.3-17.8 21.4 21.4 0 018.4-18.8z"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

Stroke version

You might need to look at the size of the scroll bar, to see how much smaller this is.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none" stroke="#000" stroke-width="4" aria-label="Chicken">
  <path d="M48.1 34C22.1 32 1.4 51 2.5 67.2c1.2 16.1 19.8 17 29 17.8H89c15.7-6.6 6.3-18.9.3-20.5A28 28 0 0073 41.7c-.5-7.2 3.4-11.6 6.9-15.3 8.5 2.6 8-8 .8-7.2.6-6.5-12.3-5.9-6.7 2.7l-3.7 5c-6.9 5.4-10.9 5.1-22.2 7zM48.1 34c-38 31.9 29.8 58.4 25 7.7M70.3 26.9l5.4 4.2"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

This is obviously far too labour intensive for web developers to carry out, but my plea to our talented and tasteful brethren on the design side is to use the smallest number of nodes you can.

A CHALLENGE?

In fact, I'd like to go further: are any designers interested in having their own version of competitions like the 5k? Design say a standard set of ten icons in as little code as possible? A handful of beautiful curves expressing concepts elegantly, both visually and in code.

I'd love to see that, then view source and witness the code.

Update

I went hunting for an icon set which fulfilled this brief, and I found one. It's called Feather and it has code as beautiful as this:

<svg
  xmlns="http://www.w3.org/2000/svg"
  width="24"
  height="24"
  viewBox="0 0 24 24"
  fill="none"
  stroke="currentColor"
  stroke-width="2"
  stroke-linecap="round"
  stroke-linejoin="round"
>
  <polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6" />
  <line x1="8" y1="2" x2="8" y2="18" />
  <line x1="16" y1="6" x2="16" y2="22" />
</svg>
Enter fullscreen mode Exit fullscreen mode

Because it's based on a 24×24 grid, frequently the points in the polygons and lines have no decimal places. It's completely from strokes and is designed to accommodate stroke widths from 1px to 3px. The only optimisation I could make to it would reduce its flexibility and readability. Well, other than the old trailing space thing, but no-one cares about that.

Top comments (0)