{"id":363179,"date":"2022-02-17T07:21:41","date_gmt":"2022-02-17T15:21:41","guid":{"rendered":"https:\/\/css-tricks.com\/?p=363179"},"modified":"2022-02-17T07:21:44","modified_gmt":"2022-02-17T15:21:44","slug":"subsetting-font-awesome-to-improve-performance","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/subsetting-font-awesome-to-improve-performance\/","title":{"rendered":"Subsetting Font Awesome to Improve Performance"},"content":{"rendered":"\n

Font Awesome<\/a> is an incredibly popular icon library. Unfortunately, it\u2019s somewhat easy to use in a way that results in less-than-ideal performance. By subsetting Font Awesome, we can remove any unused glyphs from the font files it provides. This will reduce the number of bytes transmitted over the wire, and improve performance.<\/p>\n\n\n\n

Let\u2019s subset fonts together in a Font Awesome project to see the difference it makes. As we go, I\u2019ll assume you\u2019re importing the CSS file Font Awesome provides, and using its web fonts to display icons.<\/p>\n\n\n\n\n\n\n

Let\u2019s set things up<\/h3>\n\n\n

For the sake of demonstration, I have nothing but an HTML file that imports Font Awesome\u2019s base CSS file<\/a>. To get a reasonable sample of icons, I\u2019ve listed out each one that I use on one of my side projects.<\/p>\n\n\n\n

Here\u2019s what our HTML file looks like in the browser before subsetting fonts:<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Here\u2019s a look at DevTool\u2019s Network tab to see what\u2019s coming down.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Now let\u2019s see how many bytes our font files take to render all that.<\/p>\n\n\n

Here\u2019s our base case<\/h3>\n\n\n

We want to see what the most straightforward, least performant use of Font Awesome looks like. In other words, we want the slowest possible implementation with no optimization. I\u2019m importing the all.min.css<\/code><\/a> file Font Awesome provides.<\/p>\n\n\n\n

As we saw above, the gzipped file weighs in at 33.4KB, which isn\u2019t bad at all. Unfortunately, when we peek into DevTool\u2019s Font tab, things get a little worse.<\/p>\n\n\n\n

\"Screenshot
Yikes. 757KB just for font files. For 54 icons.<\/figcaption><\/figure>\n\n\n\n

While font files are not as expensive a resource for your browser to handle as JavaScript<\/a>, those are still bytes your browser needs to pull down, just for some little icons. Consider that some of your users might be browsing your site on mobile, away from a strong or fast internet connection.<\/p>\n\n\n

First attempt using PurifyCSS<\/h3>\n\n\n

Font Awesome\u2019s main stylesheet contains definitions for literally thousands of icons. But what if we only need a few dozen at most? Surely we could trim out the unneeded stuff?<\/p>\n\n\n\n

There are many tools out there that will analyze your code, and remove unused styles from a stylesheet<\/a>. I happen to be using PurifyCSS<\/a>. While this library isn\u2019t actively maintained anymore, the idea is the same, and in the end, this isn\u2019t the solution we\u2019re looking for. But let\u2019s see what happens when we trim our CSS down to only what\u2019s needed, which we can do with this script:<\/p>\n\n\n\n

const purify = require(\"purify-css\");\n\nconst content = [\".\/dist\/**\/*.js\"]; \/\/ Vite-built content\n\npurify(content, [\".\/css\/fontawesome\/css\/all.css\"], {\n  minify: true,\n  output: \".\/css\/fontawesome\/css\/font-awesome-minimal-build.css\"\n});<\/code><\/pre>\n\n\n\n

And when we load that newly built CSS file, our CSS bytes over the wire drop quite a bit, from 33KB to just 7.1KB!<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

But unfortunately, our other Font Awesome font files are unchanged.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

What happened? PurifyCSS did its job. It indeed removed the CSS rules for all the unused icons. Unfortunately, it wasn\u2019t capable of reaching into the actual font files<\/strong> to trim down the glyphs, in addition to the CSS rules.<\/p>\n\n\n\n

If only there was a tool like PurifyCSS that handles font files\u2026<\/p>\n\n\n

Subsetters to the rescue!<\/h3>\n\n\n

There are, of course, tools that are capable of removing unused content from font files, and they\u2019re called subsetters<\/strong>. A subsetter<\/dfn> analyzes your webpage, looks at your font files, and trims out the unused characters. There are a bunch of tools for subsetting fonts out there, like Zach Leatherman\u2019s Glyphhanger<\/a>. As it turns out, subsetting Font Awesome is pretty straightforward because it ships its own built-in subsetters. Let\u2019s take a look.<\/p>\n\n\n

Subsetting fonts automatically<\/h3>\n\n\n

The auto subsetting and manual subsetting tools I\u2019m about to show you require a paid Font Awesome<\/a> Pro subscription<\/a>.<\/p>\n\n\n\n

Font Awesome allows you to set up what it calls kits<\/strong>, which are described in the Font Awesome docs<\/a> as a \u201cknapsack that carries all the icons and awesomeness you need in a neat little lightweight bundle you can sling on the back of your project with ease.\u201d So, rather than importing any and every CSS file, a kit gives you a single script tag you can add to your HTML file\u2019s <head><\/code>, and from there, the kit only sends down the font glyphs you actually need from the font file.<\/p>\n\n\n\n

Creating a kit takes about a minute. You\u2019re handed script tag that looks something like this:<\/p>\n\n\n\n

<script src=\"https:\/\/kit.fontawesome.com\/xyzabc.js\" crossorigin=\"anonymous\"><\/script><\/code><\/pre>\n\n\n\n

When the script loads, we now have no CSS files at all, and the JavaScript file is a mere 4KB. Let\u2019s look again at the DevTools Fonts tab to see which font files are loaded now that we’ve done some subsetting.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

We\u2019ve gone from 757KB down to 331KB. That\u2019s a more than 50% reduction<\/strong>. But we can still do better than that, especially if all we\u2019re rendering is 54 icons. That’s where Font Awesome\u2019s manual font subsetter comes into play.<\/p>\n\n\n

Subsetting fonts manually<\/h3>\n\n\n

Wouldn\u2019t it be nice if Font Awesome gave us a tool to literally pick the exact icons we wanted, and then provide a custom build for that<\/em>? Well, they do. They don\u2019t advertise this too loudly for some reason, but they actually have a desktop application exactly for subsetting fonts manually. The app is available to download from their site<\/a> \u2014 but, like the automatic subsetter, this app requires a paid Font Awesome subscription to actually use.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Search the icons, choose the family, add what you want, and then click the big blue Build<\/strong> button. That\u2019s really all it takes to generate a custom subset of Font Awesome icons.<\/p>\n\n\n\n

Once you hit the button, Font Awesome will ask where it should save your custom build, then it dumps a ZIP file that contains everything you need. In fact, the structure you\u2019ll get is exactly the same as the normal Font Awesome download, which makes things especially simple. And naturally, it lets you save the custom build as a project file so you can open it back up later to add or remove icons as needed.<\/p>\n\n\n\n

We\u2019ll open up DevTools to see the final size of the icons we\u2019re loading, but first, let\u2019s look at the actual font files themselves. The custom build creates many different types, depending on what your browser uses. Let\u2019s focus on the .woff2<\/code> files, which is what Chrome loads. The same light, regular, duotone, solid, and brand files that were there before are still in place, except this time no file is larger than 5KB\u2026 and that\u2019s before they\u2019re gzipped!<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

And what about the CSS file? It slims down to just 8KB. With gzip, it\u2019s only 2KB!<\/p>\n\n\n\n

Here\u2019s the final tally in DevTools:<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Before we go, take a quick peek at those font filenames. The fa-light-300.woff2<\/code> font file is still there, but the others look different. That\u2019s because I\u2019m using<\/a> Vite<\/a> here, and it decided to automatically inline the font files into the CSS, since they’re so tiny.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

That\u2019s why our CSS file looks a little bigger in the DevTools Network tab than the 2KB we saw before on disk. The tradeoff is that most of those font \u201cfiles\u201d from above aren\u2019t files at all, but rather Base64-encoded strings embedded right in this CSS file, saving us additional network requests.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

All that said, Vite is inlining many different font formats that the browser will never use. But overall it\u2019s a pretty small number of bytes, especially compared to what we were seeing before.<\/p>\n\n\n\n

Before leaving, if you\u2019re wondering whether that desktop font subsetting GUI tool comes in a CLI that can integrate with CI\/CD to generate these files at build time, the answer is\u2026 not yet. I emailed the Font Awesome folks, and they said something is planned. That’ll allow users to streamline their build process if and when it ships.<\/p>\n\n\n\n


\n\n\n\n

As you’ve seen, using something like Font Awesome for icons is super cool. But the default usage might not always be the best approach for your project. To get the smallest file size possible, subsetting fonts is something we can do to trim what we don’t need, and only serve what we do. That\u2019s the kind of performance we want, especially when it comes to loading fonts, which have traditionally been tough to wrangle<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"

Font Awesome is an incredibly popular icon library. Unfortunately, it\u2019s somewhat easy to use in a way that results in […]<\/p>\n","protected":false},"author":250838,"featured_media":363201,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"757KB for 54 icons? Yikes. Here's @AdamRackis showing how to subset Font Awesome files to trim out what you don't need.","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0","_share_on_mastodon_status":"%title% %permalink%"},"categories":[4],"tags":[1547,631],"class_list":["post-363179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","tag-font-loading","tag-icon-font"],"acf":{"show_toc":"No"},"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/02\/subsetting-fonts.jpg?fit=1200%2C600&ssl=1","jetpack-related-posts":[{"id":278151,"url":"https:\/\/css-tricks.com\/subset-numerals-so-theyre-as-awesome-as-the-rest-of-your-content\/","url_meta":{"origin":363179,"position":0},"title":"Subset Numerals so They’re as Awesome as the Rest of Your Content","author":"Charlotte Dann","date":"October 31, 2018","format":false,"excerpt":"You\u2019re putting the finishing touches on your new million-dollar-idea \u2014 your copy is perfect, your color scheme is dazzling, and you\u2019ve found a glorious font pairing (who knew Baskerville and Raleway looked so great together? You did.) but there\u2019s one problem: Raleway\u2019s pesky lowercase numbers make your shopping cart look\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/numerals-featured.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/numerals-featured.png?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/numerals-featured.png?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/numerals-featured.png?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/10\/numerals-featured.png?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":267436,"url":"https:\/\/css-tricks.com\/three-techniques-performant-custom-font-usage\/","url_meta":{"origin":363179,"position":1},"title":"Three Techniques for Performant Custom Font Usage","author":"Ollie Williams","date":"March 5, 2018","format":false,"excerpt":"There\u2019s a lot of good news in the world of web fonts! The forthcoming version of Microsoft Edge will finally implement unicode-range, the last modern browser to do so. Preload and font-display are landing in Safari and Firefox. Variable fonts are shipping everywhere. Using custom fonts in a performant way\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/02\/system-fonts.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/02\/system-fonts.jpg?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/02\/system-fonts.jpg?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/02\/system-fonts.jpg?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/02\/system-fonts.jpg?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":244593,"url":"https:\/\/css-tricks.com\/case-study-boosting-front-end-performance\/","url_meta":{"origin":363179,"position":2},"title":"A Case Study on Boosting Front-End Performance","author":"Declan Rek","date":"August 18, 2016","format":false,"excerpt":"At De Voorhoede we try to boost front-end performance as much as possible for our clients. It is not so easy to convince every client to follow all of our performance guidelines. We try to convince them by talking to them in their own language, and explain the importance of\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":205955,"url":"https:\/\/css-tricks.com\/dynamic-web-typography-with-typekit\/","url_meta":{"origin":363179,"position":3},"title":"Dynamic Web Typography with Typekit","author":"Robin Rendle","date":"August 5, 2015","format":false,"excerpt":"Typekit has started to roll out a new feature called Dynamic Subsetting which greatly reduces the size of each font file that's sent over the network. This post Tom Newton describes the current solution for doing this with Latin fonts. The process is a little hacky at the moment but\u2026","rel":"","context":"In "Links"","block_context":{"text":"Links","link":"https:\/\/css-tricks.com\/category\/links\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":306133,"url":"https:\/\/css-tricks.com\/some-typography-links\/","url_meta":{"origin":363179,"position":4},"title":"Some Typography Links II","author":"Chris Coyier","date":"April 3, 2020","format":false,"excerpt":"I just can't stop bookmarking great links related to typography. I'm afraid I'm going to have to subject you, yet again, to a bunch of them all grouped up. So those of you that care about web type stuff, enjoy. I know there are lots of good reasons to be\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":280063,"url":"https:\/\/css-tricks.com\/fighting-foit-and-fout-together\/","url_meta":{"origin":363179,"position":5},"title":"Fighting FOIT and FOUT Together","author":"Chris Coyier","date":"December 19, 2018","format":false,"excerpt":"Lots from Divya with the setup: There are 2 kinds of problems that can arise when using webfonts; Flash of invisible text (FOIT) and Flash of Unstyled Text (FOUT) ... If we were to compare them, FOUT is of course the lesser of the two evils If you wanna fight\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/12\/fight-foit-fout.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/12\/fight-foit-fout.png?fit=1200%2C600&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/12\/fight-foit-fout.png?fit=1200%2C600&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/12\/fight-foit-fout.png?fit=1200%2C600&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/12\/fight-foit-fout.png?fit=1200%2C600&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/363179","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/250838"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=363179"}],"version-history":[{"count":10,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/363179\/revisions"}],"predecessor-version":[{"id":363900,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/363179\/revisions\/363900"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/363201"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=363179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=363179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=363179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}