Loading Typekit asynchronously with yepnope.js
tl;dr: The standard Typekit embed can literally kill your website. Use a script loader like yepnope.js (or if you’re using Modernizr already, Modernizr.load
) to load it asynchronously instead.
We love Typekit. Having looked longingly at print designers add fonts willy-nilly to their projects, we jumped at the opportunity to have access to an extended library of typefaces for our web projects. The way Typekit works is you create a kit for a specific domain, add some fonts to that kit, and then add the kit to your project. To ensure that only the domains you want can use a specific kit Typekit uses a little JavaScript1 to do the validation, and they recommend you include something like the following in your HTML:
<script type="text/javascript" src="http://use.typekit.com/rndmstr1ng.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
And they specifically say:
Make sure it goes into the
<head>
tag.
This recommendation is to try to minimise the dreaded Flash Of Unstyle Text (FOUT) while the page loads.2 Great when it works, but when it doesn’t it may spell unresponsive death for your website. We found this out the hard way a little while back. Having created a brand spankin’ new site filled with beautiful Typekit fonts, the minute we flipped the switch Typekit went down (or down enough to be mostly unresponsive). Not ideal, but no biggie. Users will simply see the carefully crafted fallback fonts, right?
Wrong.
That would have been the case if Typekit had died completely, but on this occasion their server was still responding and so the browser was trying to load the linked JavaScript file but it never finished. To understand why this is a problem you need to know a little about how browsers load JavaScript:
The thing is that before fully downloading and parsing a script, the browser can’t tell what’s in it. It may contain
document.write()
calls which modify the DOM tree or it may even containlocation.href
and send the user to a whole new page. If that happens, any components downloaded from the previous page may never be needed. In order to avoid potentially useless downloads, browsers first download, parse and execute each script before moving on with the queue of other components waiting to be downloaded.– Stoyan Stefanov in Non-blocking JavaScript Downloads
See the issue? If the Typekit script include never errors and never finishes loading your page will never render. And this is exactly what happened to our newly launched site: annoucements went out, Typekit went down, and users were faced with a screen of nothing.
yepnope.js to the rescue
Using a script loader was something I’d been meaning to put into our standard toolkit for a while, but I’d never gotten around to it. There are many, many, many options out there for loading JavaScript (with dependencies) — I chose yepnope.js for this project because:
- It’s included in Modernizr (which we often use).
- It’s dead simple to implement.
- It’s made for feature-detection based script loading.
Assuming you’re using Modernizr (and have included it somewhere earlier on the page), all you need to do to load your Typekit fonts with is this:
<script>
Modernizr.load([{
// Does the browser support @font-face?
test: Modernizr.fontface, // Should return a boolean
// Yep! Get the fonts
yep : 'http://use.typekit.com/rndmstr1ng.js',
complete: function() {
// Load complete! Tell Typekit to start up
try { Typekit.load(); } catch(e) {};
// Profit!
}
}]);
</script>
The above does as the comments say:
- Test something, in this case for
@font-face
support through Modernizr. - If
true
, the URL passed toyep
will be loaded. - Add a callback for when the load is complete, which is where we do our normal
Typekit.load()
. - Profit!
If prefer you can use yepnope.js standalone, Modernizr simply aliases Modernizr.load
to yepnope
so you can use either function (and access any of the yepnope.js settings through the yepnope
object). The full documentation for yepnope.js is over at yepnopejs.com and it’s worth a read through to make sure you understand where to use it and what common issues you might run into.
None of this is intended to call Typekit out for performance problems. Stuff breaks, servers go down, pretending that nothing ever goes wrong is the real danger. While following the standard practice of including your JavaScript at the bottom of the page will mitigate this issue 99% of the time, using a script loader to load your JavaScript asynchronously will (usually) bring you some performance gains as well as a less fragile page.
Update: Sean McBride, one of the developers over Typekit, has also written up a comprehensive post on loading Typekit fonts asynchronously. His method is a little more work, but doesn’t depend on an external library (so should be a bit faster). It also provides some control over the dreaded FOUT through font events, a technique that can be used alongside yepnope.js/Modernizr too.
Most other online type providers use a CSS include instead of JavaScript for loading custom fonts so this blocking issue is not a problem.
Tune in next week for a better way to avoid the FOUT.