Optimising

Webfont Loading

Peter Müller - @_munter_

The Ideal

Users can instantly consume the most important parts of your page

The Reality

Slow Webfont Loading

<!doctype html>
<html>

<head>
  <link href="https://fonts.googleapis.com/css?family=Noto+Serif:400,700,400i|Open+Sans:700,400">
</head>

...

</html>

Recommended by Google Fonts

What can we do?

🤔

Preload

<link
    rel="preload"
    as="font"
    type="font/woff2"
    crossorigin="anonymous"
    href="https://fonts.gstatic.com/blahblah.woff2"
>

Starts download immediately

Preload Downsides

Requires known URI

Font service URI's not guaranteed stable

Solution:

Serve your own fonts

Preload Upsides

Easy

Progressive enhancement

 

Can be sent as HTTP-Header:

Link: </fonts/Roboto.woff2>; rel=preload; as=font; type=font/woff2;

Preload Support

Browser Usage: 59.79%

caniuse.com/#feat=link-rel-preload

JS Font Loading

var font = new FontFace(
    'Roboto',
    'url(/fonts/Roboto.woff2) format("woff2"), url(/fonts/Roboto.woff2) format("woff2")',
    {
        weight: 700,
        stretch: 'normal'
    }
)

font.load().then(...)

Browser choses the format it supports

JS Font Loading Downsides

Only with JS enabled

 

Verbose syntax

JS Font Loading Upsides

Widens browser support

 

Doesn't clash with <link rel="preload"> (use together)

 

Multiple format support

JS Font Loading

Browser Usage: 85.36%

caniuse.com/#feat=font-loading

CSS font-display (docs)

Browser Usage: 53.52%

caniuse.com/#search=font-display

Font Subsetting

Only download stuff you need

 

Difficulty level: Pandoras Box

Subsetting challenges

  • What characters to include?
  • Generate multiple formats
  • Replace references in code
  • Fallback for missing glyphs

What characters?

Text nodes, html attributes, list counters, different browser default stylesheets, CSS specificity, CSS content, quotation marks, text-transform, transitions, animations, CSS states (:hover et al), media queries, conditional comments, noscript, "bolder" and "lighter" font-weight

 

And many many more...

 

Automation is needed: An unsolved problem

Forget Something?

Forget Something?

Defining fallbacks

/* unicode range for font */
@font-family {
    unicode-range: U+0-10FFFF;
}


/* Prepending new font name */
@font-family { font-family: font; }
@font-family { font-family: font_subset; }

p { font-family: font_subset, font, sans-serif; }

Repetitive, Tedious

  • Generate multiple formats
  • Replace references in code

 

Each time you need new characters

Automation

Introducing Subfont

 

npmjs.com/package/subfont

Comparison: Hello world

Comparison: My Blog

Demo: Install + Use

Output

Subfont hello world output

 

Too large to fit a slide 😢

Perfect use cases

  • Static pages
  • Statically generated pages
    • Jekyll
    • Hugo
    • Gatsby
    • Wintersmith
    • Harp
  • App shells

Bad use cases

  • Dynamic backend pages
  • Full body rendered JS apps

Static analysis has to have static data to parse

Fallback Font

Monica Dinculescu: font-style-matcher

Questions

Thanks