Smaller Fonts with WOFF 2.0 and unicode-range

February 18, 2015


Link copied to clipboard

Posted by Rod Sheeter, Software Engineer

The Google Fonts and Chrome teams are constantly looking for ways to make fonts better for online content. In 2014, we deployed two big optimizations: WOFF 2.0 and unicode-range. Combined, they are reducing the size of the downloaded fonts by more than 40 percent on average. For users, that means faster download times and lower data costs!

The HTTP Archive has a graph of observed font sizes across the web, primarily in WOFF format. If we compare this to our best estimate of the savings attributable to WOFF 2.0 and unicode-range optimizations that went live in 2014, it looks like this:

WOFF 2.0 is a new font format using a new compression algorithm, Brotli, created by the Google Compression team. WOFF 2.0 responses use ~25 percent less bytes than WOFF with Zopfli.

unicode-range allows the browser to automatically select what subset(s) of the font it needs based on the particular font glyphs used on the page. In practice, we’ve observed approximately 50 percent reduction in response size on some large sites with this optimization. On average, we see unicode-range responses use ~20 percent less bytes than they would without.

So, how do you take advantage of these optimizations? The great news is, if you are using Google Fonts on your site, than you are already taking advantage of these optimizations! We’ve already done all the work to enable both WOFF 2.0 and unicode-range support for browsers that support it (see caniuse.com/woff2, caniuse.com/unicode-range) on your behalf. It’s that easy.

If you are using a different provider, or hosting the fonts yourself, then you will have to do a little bit of work to enable these optimizations:

To use WOFF 2.0, convert your fonts using a supporting editor or via the command line tools and either serve WOFF 2.0 only to supporting browsers (what we do at Google Fonts), or use a bulletproof font-face declaration similar to the following (courtesy of Font Squirrel, with svg removed):

/* Generated by Font Squirrel (http://www.fontsquirrel.com) on February 2, 2015 */
@font-face {
    font-family: 'lobster';
    src: url('lobster-webfont.eot');
    src: url('lobster-webfont.eot?#iefix') format('embedded-opentype'),
         url('lobster-webfont.woff2') format('woff2'),
         url('lobster-webfont.woff') format('woff'),
         url('lobster-webfont.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}

To use unicode-range, the story is a bit more complicated. Due to inconsistent behavior of some older browsers, which will download all subsets regardless of whether they are required, you should serve unicode-range property only to browsers that support it fully. With that in place, cut your font into pieces as you see fit (Google Fonts uses fontTools for this), and serve multiple @font-face rules, one for each segment. You can see an example of this by looking at the CSS generated by Google Fonts for a browser which supports these features (e.g. access http://fonts.googleapis.com/css?family=Lobster with Chrome).

For more tips on optimizing your fonts, see Ilya Grigorik’s Optimizing Web Font Rendering Performance. If you try any of this let us know how it works out @googlefonts!