Preload Hints For Web Fonts

Au­gust 7, 2015

Web fonts are a pop­u­lar topic in the web per­for­mance com­mu­nity. How­ever, one fun­da­men­tal prob­lem is of­ten over­looked: web fonts are lazy loaded. Can web font pre­load hints help us?

Browsers only load web fonts when there is a CSS se­lec­tor for a con­nected DOM node (i.e. one that is part of the doc­u­ment) that matches a @font-face rule. The browser can’t know that those con­di­tions are true un­til it has con­structed both the DOM and the CSSOM. In or­der to do that it needs to down­load the HTML and all the CSS files.

Web fonts do not start downloading until after both the <abbr>CSS</abbr> and <abbr>HTML</abbr> are downloaded

Down­load­ing of web fonts wait un­til both the HTML and CSS files are down­loaded. In this ex­am­ple, this in­creases the time to ren­der to about 700ms.

This is by de­sign. It en­ables lazy load­ing of web fonts by only down­load­ing a font file if it is ac­tu­ally used on the page. This makes sense. Af­ter all, why would you down­load a re­source you don’t need?

This may sound great, but lazy load­ing has one big prob­lem: it is bad for per­for­mance. Lazy load­ing makes a lot of sense when you use web fonts spar­ingly for head­lines and other dis­play type. This is no longer the case on the mod­ern web. Nearly 55% of all web­sites mon­i­tored by the HTTP Archive use web fonts. They are used to ren­der all type on a site — head­lines, body text, and even icons.

Increase of web font usage over the past X years

In­crease in web font us­age from 2012 to 2015. Source: HTTP Archive.

The av­er­age num­ber of web fonts per site has also in­creased. In the early days of web font sup­port sites used per­haps one or two web fonts for head­lines. In the past cou­ple years we’ve seen this num­ber in­crease to an av­er­age of four to five fonts per site. This is fan­tas­tic — it has raised the ty­po­graphic “bar” on the web.

Un­for­tu­nately, web fonts have be­come a per­for­mance bot­tle­neck when browsers de­cided to hide text while fonts are down­load­ing. This prob­lem is ex­ac­er­bated by the need to have both the CSSOM and DOM con­structed be­fore web fonts can even start down­load­ing! This is com­pletely un­nec­es­sary. Web de­vel­op­ers will know whether a font is used or not. Only there is no way to tell the browser.

To solve this we need pre­load hints for web fonts. If we can tell the browser that we def­i­nitely need a font, it can start down­load­ing it much ear­lier. This will sig­nif­i­cantly im­prove per­ceived and ac­tual per­for­mance. Fonts that are down­loaded ear­lier will ren­der sooner and de­crease the im­pact of block­ing ren­der­ing (or the snap that hap­pens when fall­back fonts are re­placed by web fonts).

Web fonts do not start downloading until after both the CSS and HTML are downloaded.

Web fonts us­ing pre­load hints can start down­load­ing at the same time as other re­sources linked from the head el­e­ment. Pre­load hints cut the page load time in this ex­am­ple in half, to about 300ms.

We’re in luck; the W3C is work­ing on a pre­load spec­i­fi­ca­tion that al­lows web de­vel­op­ers to pre­load any re­source us­ing <link> el­e­ments. These pre­load­ing hints will also work for web fonts (though there are some is­sues with mul­ti­ple font for­mats).

<link rel=“preload” href=“/assets/myfont.woff” as=“font”>

In this ex­am­ple, the <link rel=“preload”> re­source hint will ask the browser to start down­load­ing the font file as soon as pos­si­ble. It also tells the browser that this is a font, so it can ap­pro­pri­ately pri­ori­tise it in its re­source queue. Pre­load hints will have a dra­matic im­pact on web font per­for­mance. Browsers that sup­port pre­load hints can start down­load­ing web fonts as soon as they have seen the hint in the HTML file and no longer need to wait for the CSS.

It’s im­por­tant to point out that these are hints and not de­mands. Browsers can — and will — ig­nore them in cer­tain cases. For ex­am­ple, if a user is on a slow or ex­pen­sive data con­nec­tion it makes sense for the browser to not down­load web fonts. In the fu­ture browsers will hope­fully of­fer user pro­files that au­to­mat­i­cally pri­ori­tise or ig­nore pre­load hints so that you get the best user ex­pe­ri­ence based on your en­vi­ron­ment.

Update: Ilya Grig­orik pointed out the above is in­cor­rect: if browsers see pre­load hints they must down­load the re­source. You can use <link rel=“prefetch”> if you want the be­hav­iour I de­scribed.

Now for the bad news: the pre­load spec­i­fi­ca­tion is still a draft and cur­rently not im­ple­mented by any browser. Other re­lated fea­tures like the CSS font load­ing API and the font-dis­play prop­erty will let web de­vel­op­ers sim­u­late some of the ben­e­fits of pre­load hints. How­ever they can never be as good be­cause they rely on ei­ther JavaScript or CSS.

We re­ally need pre­load hints to im­prove web font per­for­mance.