Puttin' the eek back in geek

Saving the internet 2000 terabytes a day: fixing Font Awesome's fonts

December 8, 2016

Font Awesome, the most ubiquitous icon font on the web, just succesfully finished a Kickstarter campaign flushing a million dollars towards its creators to revamp the icon set. With a clear signal that Font Awesome isn’t going away anytime soon, let’s take a look at the technical integrity of its fonts.

As you might be aware, there’s — ehrm — discussion about whether icon fonts are a nasty hack, or a viable solution for icons. Although I got my opinions on that, today I’m here to look at how clean and optimised one of the most popular fonts of the internet is.

The question I started out with is:

Can Font Awesome’s fonts be better?

Spoiler alert! The answer is:

Yep.

With Font Awesome being used on 73 million websites now, every byte matters. And there’s quite a few things we can do to trim the fat on Font Awesome’s fonts. Let’s go through them:

Thing zero: using OTF instead of TTF

Looking at their Github, it looks like Font Awesome provides an OTF file for “desktop use” and a TTF for web use. The WOFF and WOFF2 files (as well as the legacy EOT and SVG) are derived from this TTF.

This is kinda weird, since TTF results in bigger files than OTF, and there’s no reason why you couldn’t use that OTF on the web.

So step zero would be to simply ditch the 162kB TTF file and use the 132kB OTF, and generate the other webfonts from it. Unfortunately the OTF version of Font Awesome is a little outdated and is missing some icons, so I had to work with the TTF for the remainder of this article.

Potential savings: 30 kilobytes!

Thing one: reducing the unitsPerEm

This is the real reason I wanted to jump into this experiment. During previous adventures in font deconstruction I got to play with the unitsPerEm value. In short, this value determines the coarseness of the grid the characters are drawn on. Common values in regular fonts are 1000 and 2048. When a font with a unitsPerEm of 2048 gets rendered with font-size:16px, it means that one pixel is rendered from a 128×128 grid (2048 / 16 = 128). That’s a lot of detail to render a single pixel of a character! Obviously, most of that detail gets lost at that size, but could become visible when printed as a headline or in high DPI print.

But here’s the part from the spec that caught my interest: coordinates can be stored as a short (16 bits) or a byte (8 bits). This means that this contour with eight coordinates:

<contour>
  <pt x="1000" y="750" on="1"/>
  <pt x="1000" y="500" on="1"/>
  <pt x="500" y="500" on="1"/>
  <pt x="500" y="750" on="1"/>
</contour>

needs eight shorts (or sixteen bytes) to store the x and y coordinates. But this would take only eight bytes:

<contour>
  <pt x="100" y="75" on="1"/>
  <pt x="100" y="50" on="1"/>
  <pt x="50" y="50" on="1"/>
  <pt x="50" y="75" on="1"/>
</contour>

All values below 255 fit in a byte. And with that, we saved eight bytes on this super small contour (part of a glyph shape).

A font like Font Awesome has about 100.000 coordinates for all glyphs combined, resulting in a potential savings of 100kB!

The caveat here is of course that the grid gets coarser. For a sophisticated typeface this will most likely be undesirable: detail gets lost and font won’t look as good on very large sizes. But for a relatively simple, geometric font like an icon font, a unitsPerEm value of, say, 256 should be more than sufficient.

So, long story short: the original unitsPerEm of Font Awesome’s fonts is 1792. That’s a bit of overkill, so let’s bring it down to 256. This brings the size down from 165548 bytes to 150508, saving 15kB!

Sample of the Font Awesome icon set animating between 256 and 1792 unitsPerEm
Sample of the Font Awesome icon set animating between 256 and 1792 unitsPerEm. Screenshots taken in Chrome on OSX.

But did we lose any detail? Judge for yourself: this is an image with absurdly large icons, jumping from 1792 to 256 unitsPerEm. If you look closely you’ll be able to see some differences, but at regular icon sizes, you won’t see any difference at all!

Savings: 15 kilobytes!

Thing two: removing useless cruft

Next, let’s get rid of some stuff we don’t need. The tools that generate the Font Awesome fonts stick some extra stuff in those files we can do without. There’s a super handy tool called pyftsubset (part of TTX/FontTools), which can subset and optimise fonts. Out of the box it’ll do all “safe” optimisations — lossless stuff like removing legacy tables or pruning unused stuff from tables.

Running our font through it reduces the font down from 150508 to 141376 bytes, saving another 9kB. Not super much, but since it was all dead weight anyway I say good riddance.

Savings: 9 kilobytes!

Thing three: generating super compressed WOFF and WOFF2

We’ve been working with the TTF version of the font until now. As a webfont, this is pretty useless: only some old Android devices need TTF or OTF fonts. Most browsers will want the WOFF or WOFF2 files. Let’s compress our TTF and see how small these get.

The original WOFF is 98024 bytes. Our new one, compressed with the superior Zopfli compression, is just 71632. That’s 26kB saved — a pretty big deal!

How about the WOFF2? We go from 77160 to 59000 bytes — 18kB saved. Sweet!

Savings on the WOFF: 26 kilobytes!
Savings on the WOFF2: 18 kilobytes!

Thing four: subsetting!

I originally left this out, but obviously the best way to optimise glyphs is to leave them out altogether. If you’re just using a handful of icons, there’s no need to drag along all of Font Awesome’s 675 icons. Getting a build script to go through your HTML and see which icons you use, and subset the font accordingly, would be a great way to cut the font size down enormously.

Potential savings: super much!

The final count

If each day 73 million websites serve the Font Awesome WOFF to an average of a thousand visitors who don’t have these fonts in the browser’s cache, at a 26kB savings on the WOFF, we’ve saved…

73,000,000 sites × 1,000 visitors × 26 kilobytes = 1,898 terabytes

…almost 2000 frigging terabytes (technically 2 frigging petabytes) of useless, pointless bloat! Gadzooks!

You can download the optimised files from my Font Awesome fork!

But should we do this?

Optimising font files? Oh heck, yes! Granted, trimming the fat like this isn’t as useful as other optimisations like reducing HTTP requests, optimising images or being careful with the JavaScript libraries you include. But still — downloading a pointless 26kB just to chuck it in the bin is a waste of bandwidth. If they’re sticking to icon fonts instead of SVG, Font Awesome better make their font files awesome too.

And for the question “should we even use icon fonts?” I’m going to steer clear of that discussion for now, but I’ll say this: if you’re going to do it, do it as optimised as possible!