Using Typekit the right way (with an improved embed code)

Sebastian Kippe ·

TL;DR: If you use Typekit’s advanced embed code, our improved version will dramatically improve load times for your users on slow connections or who use third-party resource blocking via e.g. browser extensions like Ghostery.

Background

At 5apps we use Webfonts for all our sites; both self-hosted icon fonts as well as beautiful typefaces hosted by Typekit (and sometimes Google).

In general, Typekit works very well, and they improved the loading process quite a bit over time. But one major problem still exists when using the advanced embed code to improve load times of your pages by not blocking all other rendering until the fonts are loaded:

If you want to hide FOUT–the “Flash Of Unstyled Text”, occuring when Webfonts are loaded after the page has been rendered with fallback system fonts–then you’ll use CSS to hide either the whole page, or the parts using Webfonts, until Typekit removes the wf-loading class from your body element.

For the case of something going wrong with loading the fonts from Typekit, the advanced embed script uses a timeout (3 seconds by default), which will trigger the wf-loading class to be removed (and a wf-inactive class to be added), if the font(s) couldn’t be loaded during that time.

Problems

The major problem with this approach is that (until the font could be loaded and cached successfully) it might take up to 3 seconds for your users to be able to see any content; not once, but for every single page load.

There are at least two more or less regular scenarios in which this will be the norm:

  • Slow Internet connections

Even if you’re not catering to low-bandwidth users on the countryside or people in developing economies, mobile networks everywhere are slow and unreliable. This could hit any one of your users.

  • Third-party resources being blocked

The regular reason for this (at least in our experience) is, that the person is using a privacy-enhancing browser extension like e.g. Ghostery, and has set it to block all 3rd-party resources, unless explicitly allowed. Another reason could be some kind of protective Web proxy (e.g. FreedomBox) being used. In either case, it’s not visible to the user why your site or application is so incredibly slow.

Solution

Our solution for this is rather simple (it took about 10 minutes to develop), yet quite effective. If the timeout is hit during a page load, we’ll just tell the browser that it shouldn’t try to load Typekit fonts anymore until the tab or window is closed.

By using the browser’s sessionStorage– the lesser-known, non-persistent sibling of the more well-known localStorage– we don’t even have to flush that configuration key, or jump through any other hoops, in order to get exactly the behaviour we want.

So, without further ado, here’s our adapted version of the advanced embed code, loading pages instantly during the rest of the visit, after running into the configured timeout for the first time:

(function(d) {
  var tkTimeout=3000;
  if(window.sessionStorage){if(sessionStorage.getItem('useTypekit')==='false'){tkTimeout=0;}}
  var config = {
    kitId: 'a1b2c3f4',
    scriptTimeout: tkTimeout
  },
  h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+"wf-inactive";if(window.sessionStorage){sessionStorage.setItem("useTypekit","false")}},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+="wf-loading";tk.src='//use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
})(document);

And here’s a Gist on GitHub.

I hope this can help you improve load times for some of your users, as it did for ours. But I’d also like to encourage you to think about potential problems on the edges of your userbase, and especially to never rely solely on third parties for your content to be available or visible. Otherwise you might end up with situations like these…

Tweet

Feedback

Please leave a comment below or ping us on Twitter (or even better yet, fork the Gist and improve it), if you find a problem with this approach or an better way of solving the problem.