Changes to web font serving on Typekit

A few weeks ago we made an announcement we didn’t like. A change in how Google Chrome loads stylesheets resulted in a jarring flash of unstyled-then-invisible text on Chrome 50 and above. We apologize for this.

Today we have good news. We have changed how Typekit loads fonts, and have mitigated the distracting flash in Chrome. We’ve also taken the opportunity to squeeze in other performance updates we’ve had in the works for a while, so you should notice speedier font loading regardless of which browser you use.

You don’t need to do anything to get these improvements; the kit JavaScript is auto-updating, so your sites are already benefiting from the new code. Enterprise customers and Typekit integration partners, such as WordPress and Squarespace, will get this same update in the coming weeks.

What changed?

To understand the change, we first need to take a look at how Typekit previously loaded fonts. When your browser loaded a web page, it requested the Typekit JavaScript. The JavaScript would run and insert a link to a Typekit stylesheet containing the fonts you had added to your kit. Once the stylesheet loaded, the fonts displayed.

Typekit's old way of serving fonts, mapped

The new way of loading fonts is slightly different. Instead of inserting a link to a stylesheet, the new JavaScript inserts a stylesheet with @font-face rules. The browser then downloads the individual font files from our font network. Since we’re no longer loading a stylesheet, this avoids the Chrome 50 problem.

New way of loading fonts, mapped

You may have noticed that with this change we’re also making individual network requests for each font file instead of bundling fonts in a single request. If you’re worried about the performance implications of this change, we have more good news for you.

Performance implications

Before making this change, we set up a new performance monitoring system that sends performance metrics back to us at random intervals. This allowed us to monitor font loading metrics before and after the change.

Our performance metrics show that the new approach results in much faster load times for fonts — as much as 300 milliseconds faster compared with the old method.

Font loading performance before and after change

The amount of time it takes to display all fonts in a kit over an eight hour period. The purple line is the old loading method; the blue line is the new method. Loading time in milliseconds on the vertical axis. Lower is better.

We attribute this improvement to a couple of other changes we made at the same time: support for HTTP/2, cross-site caching of fonts, and extended cache times.

HTTP/2 can send multiple requests over the same connection, thereby avoiding the overhead of opening an individual connection for each font. Browser support for HTTP/2 is very good, so it is very likely you’re using a browser that supports HTTP/2 already. For browsers that don’t support HTTP/2, we’ve also moved fonts to a new domain, which lowers the risk of exceeding the maximum number of connections per host and will make font loading speedier there as well.

Under our old approach to font loading, fonts embedded in the stylesheet were specific to a single kit. With individual font files that’s no longer the case, and sites can share the same font files. For example, if you visit two sites that are using the same font (and subset), your browser will download the font file only once because it’ll be cached on your visit to the first site.

We also changed the cache time for font files. Instead of the one week that we used for stylesheets, font files are cached for one year. Both of these changes improve cache hit ratios on our font network and the browser cache.

We have even more performance improvements planned, so keep an eye on this blog.

Please let us know at support@typekit.com if you have any questions or concerns about this change. We’re happy to help!

Updated August 18: Our initial post made it sound a little like our default embed code will resolve all FOUT across all browsers — we’re sorry to say, this is not quite the case. But you can use font events to manage the FOUT, or change your embed code to use async:false so our code blocks the loading of the text until fonts are available. (Read more on embed code options.)

10 Responses

  1. Violet says:

    Great news! Thank you for sharing!

  2. Jason says:

    Maybe I’m missing something but I still see that FOUT in Safari and Chrome. Do I need to do something on my end to update?

    1. Jared O says:

      Same here. I’m also seeing no improvement unfortunately.

    2. Tim Brown says:

      Jason, Jared, send a note to support@typekit.com and we’ll help sort things out. Please include a URL where you’re seeing this behavior.

  3. pallymore says:

    I’m having the same issue. Sample site: http://www.cedu.io I can see the font changes after the page is loaded.

  4. Great! It works perfectly. But does that mean that we can finally get rid of code controlling FOUT (a.k.a. adding and removing .wf-loading class)?

  5. Steve S says:

    I’m seeing it too, in Chrome 52.

    https://remotehelp.lobosstudios.com

    Not seeing it on sites that use Google Fonts – and keep in mind, I just tested the site I link to, as well as another site that uses Google, in an incognito Chrome window and therefore nothing is being cached – so obviously, they are doing something right that you are missing. Maybe look into how they load fonts?

    Here’s the thing. No Javascript is required to use a Google webfont. I’m wondering if that may be part of my problem with Typekit.

    1. htrvv says:

      Sorry – I meant “the site I linked to here”

  6. Bram Stein says:

    The fix we describe in this blog post is an unintentional FOUT caused by a change in Chrome. Those of you who are still seeing a FOUT are most likely seeing an intentional FOUT, which we made the default behaviour a while back.

    If you prefer the render blocking behaviour (FOIT) you can enable that by making a small modification to your embed code. Change async: true to async: false. This disables the asynchronous font loading that causes the FOUT you are seeing. Alternatively you could use font events to control the FOUT.

    Sorry for the confusion here. We’ll update the blog post to be clearer on this point. If you’re having trouble changing the embed code, please let us know at support@typekit.com and we’ll help you out.

  7. Have this been implemented in Squarespace yet?

Comments are closed.