1 of 16

Reducing Web Font Loading Frictions

2 of 16

<style>

@font-face {

src: url(http://my-custom/font.ttf);

font-family: custom-font;

}

div {

font-family: custom-font;

}

<style>

<div>Text rendered with a web font.</div>

Doesn’t trigger loading

Triggers loading

3 of 16

Web Font Loading Timeline

Style

Layout

Paint

...

...

Start font loading

End font loading

Invalidations

Style

Layout

Paint

...

...

4 of 16

Frictions: Latency & Unstable Layout

Style

Layout

Paint

...

...

Start

End

Invalidations

Style

Layout

Paint

...

...

10ms (e.g., from disk cache)

100ms

100ms

5 of 16

“If there's a high probability that your page will need a specific Webfont hosted at a URL you know in advance, you can take advantage of a new web platform feature: <link rel="preload">.”

-- Google Web Fundamentals

6 of 16

Race Condition: Loading vs Rendering

Start

End

Invalidations

Style

Layout

Paint

...

...

Preloading

Style

Layout

Paint

...

...

7 of 16

Solution to Race Condition

Start

End

Invalidations

Style

Layout

Paint

...

...

Preloading

8 of 16

Solution to Racing (details)

  • Before the first rendering cycle, block rendering if there’s font preloading
    • Until font preloading finishes
    • Or until a short timeout matching disk cache latency

WIP: crrev.com/c/2006626

9 of 16

‘font-display: optional’

@font-face {

src: url(http://my-custom/font.ttf);

font-family: custom-font;

font-display: optional;

}

Intention: if the font is not “immediately” available, don’t use it

  • No unstable layout

Reality: allows unstable layout

10 of 16

How ‘font-display: optional’ works currently

starts font loading

“block period” timeout

loads

doesn’t load

ignored if loads after

11 of 16

Solution to Unstable Layout

Resolved on CSSWG meeting on Jan 24:

“... change normative text for font-display optional to say that the font should never change rendering of the page ...”

Implementation change:

If an ‘optional’ font is not already available in the first rendering, it’s ignored

  • Preload it to ensure usage

WIP: crrev.com/c/2006626

12 of 16

Invalidations after web font loading

crbug.com/441925: Fonts loading cause full document style recalc

  • which also causes full document relayout

Optimizations

  • Stage 1: Partial style recalc + full relayout
  • Stage 2: Partial style recalc + partial relayout

13 of 16

Stage 1: Partial style recalc

Element style:

  • font-size: 16px;
  • font-family: custom-font, sans-serif;
  • width: 20ex;
  • ...

Element style:

  • font-size: 16px;
  • font-family: custom-font, sans-serif;
  • width: 20ex;
  • ...

loads

14 of 16

Stage 1: Partial style recalc

  • Allow reusing Font
  • Invalidate styles only for ‘ex’ and ‘ch’
    • And ‘font-size-adjust’ due to impl details
  • Manually mark layout dirty

WIP: crrev.com/c/1952189

5% improvement on Cluster Telemetry

15 of 16

Stage 2: Partial relayout

Rough idea only atm

Invalidate only those that may need a relayout/reshape after a font is loaded

16 of 16

References