The smallest SVG
Tags: svg, design, elegance
Published: 2020-07-09 17:13:51

---
title: The smallest SVG
published: true
description: A quest to find the smallest SVG possible
tags: svg, design, elegance
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/sakuh1z669qn66ld8p4p.jpg
---

Since I started embedding <abbr title="Scalable Vector Graphics">SVG</abbr>s directly into markup, I've become increasingly motivated to make them smaller. I've used [SVGOMG](https://jakearchibald.github.io/svgomg/) and [Nano](https://vecta.io/nano) both of which have taught me all kinds of tricks to shave embedded <abbr>SVG</abbr>s 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 <abbr>SVG</abbr>s are made.

If you've learned your craft as a <q>pure</q> 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 <abbr>SVG</abbr>. 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](https://thenounproject.com/iconproducer/) from The Noun Project (a wonderful resource for <abbr>SVG</abbr>s). Here's what Iconic's <q>chicken</q> 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](https://dev-to-uploads.s3.amazonaws.com/i/25kg998dopwh2bstt70f.png)

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 <abbr>SVG</abbr>s

Look, I don't know much about *creating* <abbr>SVG</abbr>s, 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)
1. Pointy or curvy lines, which you can only see when they get a <q>stroke</q> 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](https://dev-to-uploads.s3.amazonaws.com/i/bv0nz09rpv67jdwefck6.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/kvews3bmf62eahxcopur.png)

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

## Original

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

```xml
<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>
```

## Stroke version

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

```xml
<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>
```

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](https://the5k.org/)? 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](https://feathericons.com/) and it has code as beautiful as this:

```xml
<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>
```

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](https://dev.to/rossangus/html-junk-dna-19k1), but no-one cares about that.