How to use asynchronous font loading

Rob Madole
Font Awesomeness
Published in
7 min readAug 18, 2016

Recently we announced a release of our asynchronous loader which is available through all of our kits on Fort Awesome. With it came some backward-incompatible changes that we felt were needed to clean up our initial release.

One comment we’ve received from a lot of users is: “How do I use this?” So we thought we’d take time to go over some patterns for async font loading and how you can use this feature.

What is synchronous (or blocking) loading?

Fort Awesome uses CSS features to load your icons and any typefaces you have from your kits. This CSS is loaded through JavaScript. Our embed code https://use.fortawesome.com/a97ca672.js adds a <link> tag to the <head> of the page to make this happen.

With normal synchronous loading the browser will see this addition to the Document Object Model (DOM) and block rendering of the page until the CSS finishes loading. For your main site’s CSS this is exactly what you want. If the browser didn’t wait on this CSS you would get a flash of unstyled content before seeing the real page.

While you care about your main CSS, your icon font and typefaces are probably not critical enough to block page rendering. We want our pages to load and display content to the user as quickly as possible. Loading a site just 1 second faster can yield drastic improvements in conversion rates.

What is asynchronous (or non-blocking) loading?

With asynchronous loading the JavaScript triggers the browser to load the same CSS in a way that does not block the rendering of the page.

This causes content on the page to be displayed before the icons or typefaces from your kit are finished loading. This has a positive effect on performance while having some negative effects on how the content is displayed.

With Fort Awesome and Font Awesome CDN you have the option of choosing either normal loading or asynchronous loading.

What’s next?

There are some potential downsides to asynchronous loading we’ll cover in detail:

  1. Flash of unstyled text (FOUT) — text that displays to the visitor in the default browser font because the real typeface hasn’t loaded
  2. Flash of invisible text (FOIT) — text that is missing from the page until the typeface has loaded
  3. Invisible font variant text — bold or italic variants that show up as gaps in otherwise visible text until the typeface variant is loaded
  4. Layout shifting — elements utilizing icons that suddenly get wider after the icon font has loaded

Yuck, right? These don’t only occur on slower connections or under failure conditions but can happen at any time. Luckily we have some techniques to handle it.

Font events from Font Awesome CDN and Fort Awesome

The first step in conquering some of these drawbacks is providing our customers with the tools to craft their solution.

We’ve built on top of the great work from Bram Stein and Filament Group to provide font events to both our platforms.

Let’s go source-diving and take a quick look at an example:

fa-events-icons-ready added to the <html> tag

All font events will be represented as class attributes on the <html> tag of the page. The embed code or kit JavaScript will automatically add these for you.

fa-events-icons-[“loading”|”ready”|”failed”]

This event indicates the status of the icons for the page. While icons are loading you’ll see “fa-events-icons-loading”. After they finish you’ll see “fa-events-icons-ready”. Should the icons fail to load you’ll see “fa-events-icons-failed”.

fa-events-typefaces-[family]-[“loading”|”ready”|”failed”]

This event indicates the overall loading status of an individual typeface. An example would be “fa-events-typefaces-lato-ready”.

fa-events-typefaces-[family]-[weight]-[style]-[“loading”|”ready”|”failed”]

This more specific typefaces event includes weight and style to provide more specific targeting by font variant. An example would be “fa-events-typefaces-lato-300-normal-ready”

Deciding how your page will load

There is no magic solution. Ultimately, you have to decide how you want your pages to load. Here are the most common things that we’ve ran into and how you can implement them using Fort Awesome and Font Awesome CDN. If you have other ideas we’d love to hear about them.

For this example I’m using Fort Awesome with an icon from Black Tie, 2 custom icons, and 4 typefaces. Fort Awesome makes it easy to pull all those pieces together. You can start a 14-day trial and try it out for yourself.

Without any modification this is how our page loads:

Left: flash of unstyled text and missing icons, Right: icons and typefaces loaded

Using a fallback font

Problem: the transition between the browser’s default font and the site’s typeface is very jarring

Solution: use a fallback font that is closer to the site’s actual typeface

Left: fallback font “sans-serif”, Right: Lato typeface

Since Lato is used in the actual design of this page we can fallback to a sans-serif typeface to minimize the visual difference between it and the browser’s default Times Roman.

See the code on codepen.io

By using “fa-events-typefaces-lato-loading” in combination with our elements that use Lato we can target just those elements and change the font-family to “sans-serif”.

Hiding elements that require icons or typefaces

Problem: some elements require icons or typefaces to make visual sense to the user and shouldn’t be displayed until they are ready

Solution: surgically hide elements or sections that require icons or typefaces until they are loaded

Left: hidden section, Right: section visible after icons and typefaces loaded

With this example we completely hide the Mr. Fusion logo until the typeface and icon are loaded. The main content is available right away and since we are using “visibility: hidden;” space is still present in the page for the brand to fill.

See the code on codepen.io

Keeping icons from messing with your layout

Problem: the layout of buttons and other elements shift drastically after the icons load causing the page to reflow

Solution: use fixed layout icons and create a placeholder for them

Left: placeholders create holes in the layout, Right: placeholders filled after icons loaded

This approach utilizes “fa-fw” to make icons a fixed width. We then use some additional CSS to create placeholders in the content.

See the code at codepen.io

Here the loading state is used to target all “fa-fw” elements and force them to be inline-block. The width 1.28571429em; comes from the “fa-fw” definition. By matching these two values our icons will not experience any shifting while they are loading.

The section definition “fa-fw::before” targets the icons content. In order for the browser to display the placeholder it has to have some text in it. “\00a0” is a non-breaking space and works great for this purpose.

Add fa-fw to any icon that needs to become a placeholder

The last step in this scenario is to add “fa-fw” to the icons that should be placeholders on the page.

Blocking display of everything until icons and typefaces are loaded

Problem: when the page loads there is a brief moment when the text is the wrong font (FOUT) or is not visible (FOIT)

Solution: hide the entire <body> until the icon and typefaces are loaded

This is the nuclear option and we do not recommend it. It’s much better to use specific techniques to accomplish nuanced effects. But, sometimes you need the nuclear option.

See the code on codepen.io

By using the “fa-events-icons-loading”, “fa-events-typefaces-lato-loading”, and “fa-events-typefaces-orbitron-loading” we can hide the entire <body> of our page until they are ready.

This solution works well if the icons and fonts should fail to load because the “loading” states will get replaced with “failed”. With the loading state missing the body will be displayed as normal.

While this technique avoids FOUT, FOIT, and any layout issues it’s the slowest approach. It’s also very similar to normal blocking loading. So if this approach sounds like the behavior you want you might also consider turning async loading off.

Bringing it all together

Surgically hiding, fallback font, fixed-width icons. See it on codepen.io.

Combining three of the mentioned techniques we finish off with an example that still displays the main content while minimizing layout and visual shift. With a little more work we could get things even closer.

Hopefully this provides some useful examples of how you can leverage asynchronous loading to get better performance while managing the trade-offs that come with it.

If you have any suggestions, comments, or issues please let us know about it!

--

--

Rob Madole
Font Awesomeness

Developer in the smack-dab middle of the United States. I work at Font Awesome.