Smashing Book 5: Web Fonts Performance

July 28, 2015

Smash­ing Mag­a­zine asked me to write a chap­ter about web fonts per­for­mance for Smash­ing Book 5. I think web fonts are great, but they suf­fer from one big prob­lem: by de­fault they block ren­der­ing in al­most all browsers. You may have ex­pe­ri­enced this your­self on a site us­ing web fonts while us­ing a slow cel­lu­lar net­work. Star­ing at a blank page is no fun, es­pe­cially when the con­tent has al­ready loaded.

Smashing Book 5

Block­ing ren­der­ing while down­load­ing fonts is wrong and against the very idea of pro­gres­sive en­hance­ment. Af­ter all, the con­tent is what peo­ple come for. Web fonts are an en­hance­ment of that con­tent. Im­por­tant, but not crit­i­cal. This chap­ter will show you how to op­ti­mise web fonts and how to load them with­out in­con­ve­nienc­ing your vis­i­tors.

Table of Contents

Be­low is the table of con­tents with a short de­scrip­tion of each sec­tion to give you an im­pres­sion of what is cov­ered in the chap­ter.

Web Fonts & Formats

The chap­ter starts with a short in­tro­duc­tion to the @font-face syn­tax, and an overview of all web font for­mats: TTF, OTF, EOT, WOFF, WOFF2, and SVG fonts. It cov­ers the browser sup­port for these for­mats and their ben­e­fits and down­sides. Fol­low­ing that is a dis­cus­sion of the bul­let­proof @font-face syn­tax and why you should no longer use it. The sec­tion ends with a rec­om­men­da­tion for which for­mats are re­quired to cover all mod­ern browsers and a pro­posal for a sim­pli­fied @font-face syn­tax.

Font Loading

Do you want to know ex­actly how browsers load web fonts? This sec­tion is for you: it con­tains a deep-dive into font load­ing. You’ll find out why browsers need to con­struct both the DOM and CS­SOM be­fore they can start load­ing web fonts. It also ex­plores how fonts are matched and un­der which cir­cum­stances fall­back fonts are used. You’ll also learn what faux styles are and how to pre­vent them.

FOUT vs. FOIT

The sec­tion ends with a de­scrip­tion of the two dif­fer­ent ap­proaches browsers take when load­ing fonts: the Flash Of Un­styled Text (FOUT) and the Flash Of In­vis­i­ble Text (FOIT). The sec­tion also con­tains in­for­ma­tion on which browsers use FOUT and which use FOIT with a time­out (or not).

CSS font-rendering property

The font-rendering* prop­erty is a pro­posal for a CSS prop­erty that con­trols how fonts are loaded. It lets you con­trol if fonts should block ren­der­ing, or if the fall­back font should be shown while load­ing web fonts. It also lets you cus­tomise the time­out the browser uses while load­ing web fonts. Even though this prop­erty has not yet been stan­dard­ised (and is likely to un­dergo changes) it shows you what will be pos­si­ble in the fu­ture.

* The prop­erty has been re­named to font-display and un­der­went other sig­nif­i­cant changes af­ter the book went to print. Check the lat­est draft pro­posal for up­dates.

CSS Font loading API

The CSS font load­ing mod­ule in­tro­duces a new JavaScript API to load and ma­nip­u­late web fonts. In this sec­tion you’ll learn how to use the API to cre­ate new @font-face rules and in­sert them into the doc­u­ment. You can also use the API to query and change ex­ist­ing @font-face rules, or to pre­load web fonts so that they do not block ren­der­ing while load­ing.

The API is cur­rently only sup­ported by Chrome, Opera, and Fire­fox. If you want to use it right now in all browsers, you can use a poly­fill that I’ve writ­ten.

Basic Optimisations

Be­fore you move on to the ad­vanced font load­ing strate­gies in the next sec­tion you should make sure you’ve cov­ered these ba­sic op­ti­mi­sa­tions to make your fonts load faster: us­ing fall­back fonts, caching, com­pres­sion, in­lin­ing and sub­set­ting.

It is tech­ni­cally not an op­ti­mi­sa­tion, but some­times the best way to make your site ap­pear faster is to show fall­back fonts be­fore load­ing web fonts. You can in­crease the per­ceived per­for­mance of your site by se­lect­ing fall­back fonts that closely match the met­rics of your web font. This sec­tion will tell you how to struc­ture your fall­back font stacks so they work well across plat­forms and de­vices.

This sec­tion also cov­ers ef­fi­cient caching of web fonts, com­pres­sion us­ing GZIP and the more ef­fi­cient Zopfli com­pres­sion al­go­rithm. In­lin­ing fonts in your stylesheets might seem like an at­trac­tive op­tion, but there are sev­eral down­sides that might make you re­con­sider this ap­proach.

The fi­nal “ba­sic” op­ti­mi­sa­tion is sub­set­ting: mak­ing fonts smaller by re­mov­ing char­ac­ters. While this is of­ten a dan­ger­ous op­er­a­tion, it can also sig­nif­i­cantly re­duce the file size of your fonts. Com­bined with the unicode-range prop­erty sub­set­ting can sig­nif­i­cantly in­crease your web­site’s per­for­mance.

Font Loading Strategies

This sec­tion con­tains sev­eral strate­gies for get­ting con­sis­tent and ef­fi­cient cross-browser font load­ing that avoids block­ing ren­der­ing. It teaches you how to load fonts se­lec­tively us­ing me­dia queries and CSS classes. This can be very use­ful when you’re only us­ing a font when cer­tain con­di­tions are true.

This sec­tion also shows you how to man­u­ally im­ple­ment FOUT and FOIT us­ing JavaScript. You can use this to make your font load­ing be­have con­sis­tently in all browsers. Man­ual font load­ing us­ing JavaScript is asyn­chro­nous and gives more more con­trol over how your web fonts are cached.

If you need to load a lot of fonts, you should con­sider pri­ori­tised load­ing. By pri­ori­tis­ing a pri­mary group of fonts you can make your site ap­pear to load faster and still load a lot of fonts.

Where to get the book

The book can be pur­chased at the Smash­ing Mag­a­zine web shop in hard­cover and eBook ver­sions. The au­thor (and re­viewer) line-up is amaz­ing, so I highly rec­om­mend get­ting a copy.

Buy Smash­ing Book #5

My thanks go out to my amaz­ing re­viewer Zach Leather­man – his feed­back and com­ments were in­valu­able. Many thanks as well to Nathan Ford, Tim Brown, and Gre­gor Ka­plan for re­view­ing and com­ment­ing on my early drafts.