Shrink Your Symbol Fonts

󰃭 2024-10-14

Create a Custom Font Subset with Just the Glyphs You Need

Imagine you’re sprucing up your website. You want crisp, scalable icons for RSS, Twitter, Instagram, and/or GitHub. You are no designer and you don’t want to mess around creating SVGs, so you opt for a symbol font - an excellent choice if I do say so myself. But then you realise it’s a whopping 900KB and includes glyphs for just about everything under the sun. All you need a handful of symbols, maybe SVGs were not such a bad idea after all…

But wait! What if we could extract just the glyphs we want and then package those up into a new font file, tossing out all the ones we don’t need in the process? Well, you can! The process is called font subsetting and the result is a tiny, efficient font file that’s perfect for web use.

Let’s Get Subsetting

Enter fonttools, a Python package that (among other things) makes subsetting fonts a fairly painless and straight forward:

Step 1: Install fonttools

First things first, you’ll need to get fonttools up and running. Open your terminal and run:

pip install fonttools

You will need recent version of python, see the foottools github for more information. I had a warning about the package brotli being required, if you get something similar just do the following

pip install brotli

Step 2: Identify Your Glyphs

Next, figure out the Unicode numbers for the glyphs you want to use. FontForge is a decent option for this or if you are using a Nerd Font then the cheat sheet lets you search by keyword and gives you the hex code for each symbol. For instance, if you’re after just the RSS and GitHub icons, you might find something like this:

  • RSS Glyph: U+F09E
  • GitHub Glyph: U+F09B

(If you find 4 character hex values then just prefix U+ to those as above)

Step 3: Subset Your Font

Now, let’s subset that massive font file. Use the pyftsubset command provided by fonttools:

pyftsubset symbols-nerd-font.woff2 \
 --output-file=symbols-nerd-font__reduced.woff2 \
 --flavor=woff2 \
 --unicodes=U+F09E,U+F09B

This command tells fonttools to take your original symbols-nerd-font.woff2, extract only the RSS and GitHub glyphs, and output a new woff2 file.

Note: you might encounter a warning like:

WARNING: PfEd NOT subset; don't know how to subset; dropped

I did. Despite the warning, the resulting file should work fine. In my case, the reduced font was a mere 900 bytes—a staggering 99% reduction from the original size.

Why Bother?

Firstly, if you made it this far, well done, I would have cut and pasted the code snippets and be long gone by now. Kudos to you!

You might be thinking, “Is packing a custom font really worth the effort?”. I guess that depends on your priorities. Me? I want my web pages to be blazing fast, performance is a feature dammit and I love seeing that 100 mark in Lighthouse. Also, downloading less data means using less bandwidth. If you pay for that and your site gets Hackernews’ed then keeping things lean will save you money.

Wrapping Up

Subsetting fonts might seem OTT at first, but with tools like fonttools, it’s a pretty straightforward process that can save your website from unnecessary bloat. So next time you’re eyeing a symbol font, remember: you don’t have to take the whole package. Just take what you need and keep your site lean and Lighthouse test green.