Beginners Guide to Web Performance: Optimizing FontAwesome Icons
Tags: webperf, webdev, fonts, frontend
Published: 2021-10-11 00:09:57

I'm a huge fan of font icons since they make updating or adding icons on the fly so much easier. I used to have to create spritesheets, which are giant images composed of custom designer-created icons and their hover states. When you wanted a specific icon from the spritesheet, you'd call the same image but set the background position in your CSS to the location in the spritesheet, which is as tedius as it sounds. Custom icons are much easier served in SVGs now, but if you want a huge set of standard icons, then font icons are incredibly convenient. 

However, if you want to maximize performance, dumping the entire font icon files in your site is not the best way to go. I'm going to discuss how to optimize the CSS/SVG implementation of FontAwesome. These will also be basic icon use, meaning just the icons and their hover states.

## FontAwesome and Font Icons

* [Download FontAwesome Files and Serve Locally](#download)
* [Using FontAwesome like a Font](#font)
    - [Understanding the CSS Files](#css)
        - [FontAwesome Free](#free)
        - [FontAwesome Pro](#pro)
* [Preload the Necessary Font Files](#preload)
* [Ditch the Files and Use FontAwesome SVGs](#svg)

## Download FontAwesome Files and Serve Locally <a name="download"></a>
Font Awesome gives you a huge number of icons for free and the ability to download and serve the files from your own server, so start with [downloading the zip folder (version 5.15.4 as of this post)](https://fontawesome.com/download) instead of using the CDN link. As is the case with normal font optimization, this helps with site speed since we don't need to access an external server to serve fonts.

## Using FontAwesome like a Font <a name="font"></a>
If you are planning to use a lot of icons and need the ability to style them differently depending on their use (or need them to inherit the text styling of their parents), then it will be easier to use them as normal fonts using the `<i>` tags.

Since we're treating FontAwesome like any other external text font that needs to load locally, then you will need the actual font files (woff, woff2, etc). These are located in the `webfonts` folder. Place that folder in your directory at the same level as your `css` folder (or wherever your stylesheets are located).

### Understanding the CSS Files <a name="css"></a>
This is where FontAwesome gets very confusing because there are a lot of individual files that come in the zip folder. Which files do you actually need in your project? Here's an explanation of the files:

- `min` is the respective minified version of the regular file. You should always load this file instead of the regular one to save space.
- `all.min.css` contains `fontawesome.min.css` (which stores the unicode value of the fonts) AND all the specific font families that tell the browser which font files to load (`regular.min.css`, `solid.min.css`, etc.)
- The font family CSS files are also separated out into individual files and cannot be used just by themselves. They will need to be used in combination with `all.min.css` or `fontawesome.min.css`

#### FontAwesome Free <a name="free"></a>

Using the free version is simpler to optimize mainly because your options are much more limited compared to Pro. You'll call one minimized file in your CSS before your own custom CSS file:

```html
<!-- Allows you to use all the free font icons -->
<link href="./css/all.min.css" rel="stylesheet">
```
Theoretically, if you only used one type of icon on your entire site (for example: Brands), you should only load that type in combination with the base FontAwesome CSS, which would look like this:

```html
<!-- Doesn't save that much data on the free version -->
<link href="./css/fontawesome.min.css" rel="stylesheet">
<link href="./css/brands.min.css" rel="stylesheet">
```

Notice we are no longer loading the `all.min.css` because the all file loads additional font types like Solid and Regular which aren't being used. However with the free version, because there are fewer types of icons, this doesn't save much space. The file `fontawesome.min.css` is only 2 KB smaller than all.min.css, and if you add `brands.min.css`, it's only about 1.3 KB less.

So if you're using the free version, you should be fine with using the `all` file and not have an issue with calling any of the free icons like so:

```html
<head>
  <link href="./css/all.min.css" rel="stylesheet">
</head>
<body>
  <i class="fab fa-dev"></i>
</body>
```

#### FontAwesome Pro <a name="pro"></a>

If you're using the Pro version you have a **lot** of options and probably more than you need. The CSS files are much larger compared to the free version. The instructions are the same as for the free version **except** you can maximize performance if you are not using Duotone icons.

If you do **not** need Duotone, then load the `fontawesome` CSS file and any of the styles needed:

```html
<!-- Load the fontawesome min and only the font styles you're using -->
<link href="./css/fontawesome.min.css" rel="stylesheet">
<link href="./css/brands.min.css" rel="stylesheet">
<link href="./css/regular.min.css" rel="stylesheet">
<!-- add any additional font style css files needed -->
```

The Duotone CSS specifically adds 80 KB of page-blocking rendering time, so it makes sense to not load it for the Pro version if you don't need it.

## Preload the Necessary Font Files <a name="preload"></a>

Regardless of whether you're using the Free or Pro version, now we need to optimize the display of the fonts on the page. In my [previous post](https://dev.to/dianale_dev/beginners-guide-to-web-performance-optimizing-google-fonts-1lif) on web performance for fonts, I recommended using `display: swap` on externally loaded fonts in order to load a fallback while the preferred font is loading. This unfortunately doesn't work for font icons as there is no built-in browser font to display while FontAwesome or any other font icon loads. So font icons will either display the icon or display nothing while they load.

What this means is that if you have font icons that need to display immediately on the web page, you should preload the font files so that they load immediately for the user, and there is minimal CLS (cumulative layout shift). You will need a `preload` attribute for __every__ type of icon style used:

```html
<!-- loading FontAwesome Brands and Regular using Pro version-->
<link rel="preload" href="./webfonts/fa-brands-400.woff2" as="font" crossorigin>
<link rel="preload" href="./webfonts/fa-regular-400.woff2" as="font" crossorigin>
<link href="./css/fontawesome.min.css" rel="stylesheet">
<link href="./css/brands.min.css" rel="stylesheet">
<link href="./css/regular.min.css" rel="stylesheet">
```

## Ditch the Files and Use FontAwesome SVGs <a name="svg"></a>

What if you just need to load a few icons or don't mind adding new CSS rules for new icons? You can ditch the CSS and font files files entirely and only use the `/svgs` folder. This is what I did for my personal portfolio site where I only used icons in a social media bar and in a few other buttons. Fortunately FontAwesome provides all the svg files for their icons.

### Insert the Font as an Image

You can load the icon directly as an image with the SVG file as the image source:

```html
<img src="./svgs/brands/dev.svg" alt="" />
```

This is fine if you don't need a hover state and the icon is used for display purposes only, but doesn't give you control over the colors.

### Insert the SVG Code Directly

This method gives you more control over styling and will allow you to set hover states. You'll need to open the SVG file directly in a code editor and then paste the code to your site. Here's an example using the Dev icon as part of a link:

```html
<a href="#" class="icon__dev" aria-label="Visit My Dev.to">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M120.12 208.29c-3.88-2.9-7.77-4.35-11.65-4.35H91.03v104.47h17.45c3.88 0 7.77-1.45 11.65-4.35 3.88-2.9 5.82-7.25 5.82-13.06v-69.65c-.01-5.8-1.96-10.16-5.83-13.06zM404.1 32H43.9C19.7 32 .06 51.59 0 75.8v360.4C.06 460.41 19.7 480 43.9 480h360.2c24.21 0 43.84-19.59 43.9-43.8V75.8c-.06-24.21-19.7-43.8-43.9-43.8zM154.2 291.19c0 18.81-11.61 47.31-48.36 47.25h-46.4V172.98h47.38c35.44 0 47.36 28.46 47.37 47.28l.01 70.93zm100.68-88.66H201.6v38.42h32.57v29.57H201.6v38.41h53.29v29.57h-62.18c-11.16.29-20.44-8.53-20.72-19.69V193.7c-.27-11.15 8.56-20.41 19.71-20.69h63.19l-.01 29.52zm103.64 115.29c-13.2 30.75-36.85 24.63-47.44 0l-38.53-144.8h32.57l29.71 113.72 29.57-113.72h32.58l-38.46 144.8z"/></svg>
</a>
```

Now that we're using the SVG code, we can style the size and color of the icon like so:

```css
.icon__dev svg {
  height: 1rem;
  fill: blue;
}
```

In this case, the SVG files are not needed at all because you're pasting the code directly into the HTML, but still keep the SVGs for reference somewhere if you need to add more icons later.

## Conclusion

Font icons are a convenient way to load a large number of icons on your site, but convenience can come with bloat. Making sure to only load what you need will help you minimize some precious first paint blocking time on your sites.