At Buffer, we’re constantly experimenting with ways we can improve our products and try out new ideas. We recently launched Start Page, a beautiful, flexible, mobile-friendly landing page that you can build in minutes and update in seconds. As a Software Engineer on Buffer’s team I’ve tackled a long list of fun projects, including Start Page. One thing I love about this project, is that as we foray deeper and deeper into user-generated content and customization, we’re discovering new engineering challenges that we haven’t had in our frontends before. In this case, we wanted to introduce 13 new font options (for a total of 16 fonts) and we wanted to make sure that they loaded nice and quickly. As I worked on this, I learned so much I didn’t know about fonts so in this post I want to share more about how we went about this for anyone facing similar challenges.

A screen capture of the Start Page app, demonstrating the new font picker functionality

Fonts are render-blocking

Let’s start with the ‘why’. Fonts are generally pretty light resources, which are usually cached in browser so why is it important to ensure a quick loading strategy? Because fonts are high-priority, synchronous requests which means they’re render-blocking. If we can load fonts quickly and/or asynchronously, we can improve site speed.

FOUT and FOIT

Ok, so you don’t want to block your rendering, there are generally two strategies to chose from to handle text loaded before it’s custom font:

FOUT - Flash Of Unstyled Text
Renders the text but with a fallback font. Google Fonts can now return with display=swap which instructs the browser to use the fallback font to display the text until the custom font has fully downloaded. If you want to be meticulous, you can find a better fallback font using this app: Font Style Matcher

FOIT - Flash Of Invisible Text
Here, the text is rendered with an invisible font until the custom font has fully downloaded. This one makes more sense to use for something like a logo where the brand would be affected if rendered with a fallback font (although for a logo I’d use an SVG but examples!)

THE trick for fast fonts

The general advice nowadays is to preconnect to the font server:

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link rel="preconnect" href="https://fonts.googleapis.com" />

then preload the fonts:

  <link
      rel="preload"
      as="style"
      href="https://fonts.googleapis.com/css2?family={your font families here}&display=swap"
    />

Finally as a fallback, request the fonts async by setting media to “print” for browsers which don’t support rel="preload" (about 12% of browsers in this the year 2021)

<link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family={your font families here}&display=swap"
      media="print"
      onload="this.media='all'"
    />

This works because a regular stylesheet is render-blocking but a print stylesheet is assigned idle priority. After it’s loaded, the link’s media is applied to all.

Hosting your own fonts is the fastest but Google Fonts does a lot for you:

  • Returns multiple alphabets
  • Returns a css file customized to the user agent that requested it
  • When you have multiple fonts, it’s best to make 1 request so it's quicker
  • You can tailor your requests to target specific font-weights and formats (bold, italic, thin)

Font Loading API

There’s a new-ish CSS Font Loading API that can request fonts on demand but I found that this doesn’t play nice with Google Fonts because you need the source URL for the fonts and the Google Fonts URL that you get isn’t the source, it’s the request. Google, along with Typekit, does have a library called Web Font Loader, that works like the Font Loading API but plays better with Google Fonts.

So what did we do in Start Page?

We implemented the popular strategy for the builder (the app itself) and while we do have some FOUT on first load ever (remember browser caching!) it’s very minimal, if seen at all. For generated pages, we get the fonts used in the theme before generating the HTML so we can inject only the fonts we need. This makes our generated pages much faster and lighter.We’re excited to see how this experiment will play out and if folks are keen to get more font options. If that’s the case, we might very well look into a more dynamic strategy (like loading only the currently used fonts on load and then sending another request if a user clicks on Appearance to change their fonts). Another option we could look into is implementing a way for requesting multiple fonts if we hosted them ourselves.

That’s it for now! Thanks for making it this far, I hope this was interesting for you! Know anything neat about fonts that I didn’t mention here? Share it with us on Twitter.

Resources:
The Fastest Google Fonts
Loading Google Fonts and any other web fonts as fast as possible in early 2021
FOIT vs FOUT: a comparison on web font loading
CSS Tricks - font-display

Brought to you by

Never miss an update from us. Join 100,000+ marketers and leaders.

Join for free

Join 160,000+ small businesses like yours that use Buffer to build their brand on social media every month

Sign up for free
  • No credit card required
  • Cancel anytime