Custom fonts slowing you down? We can fix that!

How we control downloadable fonts and rendering in the browser for a smooth user experience.

Taylor Cooney
3 min readJan 21, 2019

This article was written and proofread in Grammarly.

We’re early into our venture at Startup Jobs Toronto but we’re optimistic about the future, and want to make sure the website can handle large requests while preserving the front-end design of the website.

Speed is king on the web and un­for­tu­nately, web fonts have be­come a per­for­mance bot­tle­neck; at Startup Jobs Toronto we want the browser to use our custom font as early as possible to help match our branding. The three strategies provided below will speed up your custom font loading and the solutions are all easy to implement, you just need to budget the time!

Preloading @font-faces

Before loading fonts through preload_link_tag. This is very important leading to the First Meaningful Paint.

If we can tell the browser that we def­i­nitely need a font, it can start down­load­ing it much ear­lier. This will sig­nif­i­cantly im­prove per­ceived and ac­tual per­for­mance time; fonts that are down­loaded ear­lier will ren­der sooner and de­crease the im­pact of block­ing ren­der­ing (or the swap that occurs when fall­back fonts are applied by web fonts).

Rails includes a ActionView::Helper method called preload_link_tag that we’ll use to tell the browser to preload the source (notice that we can set a path from a font resource managed by the asset pipeline). This also sets the font as a low priority and leaves it up to the browser to decide what it thinks is most critical to load for the user based on their network connection.

## app/views/layouts/applications.html.haml= preload_link_tag("graphik/Graphik-400-Regular.otf")
= preload_link_tag("graphik/Graphik-500-Medium.otf")
= preload_link_tag("graphik/Graphik-600-Semibold.otf")

Checking for local fonts

When a custom font is loaded into the browser, a swap occurs when fall­back fonts are replaced by web fonts. This swap creates an inevitable “blank” space that’s displayed as the font is loaded into the browser. This delay can vary but our goal is to reduce the perceived impact on the users end as much as possible. So what if the user has the font installed on their machine already? Does it make sense that they have to download the font again?

The answer is no. The way to get around this is quite simple; use local() to check if the font is on the user’s system.

@font-face {
font-family: 'Graphik';
font-display: swap;
src: local('Graphik Regular'), url("/fonts/graphik/Graphik-400-Regular.otf") format("opentype");
font-weight: 400;
}
@font-face {
font-family: 'Graphik';
font-display: swap;
src: local('Graphik Medium'), url("/fonts/graphik/Graphik-500-Medium.otf") format("opentype");
font-weight: 500;
}
@font-face {
font-family: 'Graphik';
font-display: swap;
src: local('Graphik Semibold'), url("/fonts/graphik/Graphik-600-Semibold.otf") format("opentype");
font-weight: 600;
}

The cascade is used so that only if the local condition isn’t met (that is, the font is not on the user’s system) will the browser begin to load the font into the cache. Don’t forget to declare the rule for each face (regular, medium, semibold etc.).

Leveraging @font-display

@font-face allows developers to decide how their web fonts should render (or fallback), depending on how long it takes for them to load. By adding the @font-display attribute, we can use the swap value to let the browser draw text immediately with a fallback if the font face isn’t loaded, and swap the font face in as soon as it loads. See the code snippet above for how we leveraged this, and check out the Controlling Font Performance with font-display to learn more about font-display and how it can be leveraged in your app, below is an excerpt from their guide that explains the swap value in-depth.

This value should only be used when rendering text in a particular font is important for the page, but rendering in any font will still get a correct message across. Logo text is a good candidate for swap since displaying a company’s name using a reasonable fallback will get the message across but you’d eventually use the official typeface.

This article is part of an ongoing series that documents simple ways to improve an apps performance, with a focus towards the Ruby on Rails framework. Going beyond advice and theory, all discussed methods are tested on www.startupjobstoronto.com.

--

--

Taylor Cooney

Ruby on Rails Developer at Universe. Previously Nudge Rewards and Kik.