Slide 1
WHYs THE 5 WHYs OF WEB WHYs LOADIN WHYs PERFOR WHYs
Slide 2
WHYs WHYs OF WEB FONT WHYs LOADING WHYs PERFORMANCE WHYs
Slide 3
@zachleat @zachleat.com @Web Craftsperson
Slide 4
@zachleat
HY WHY WHY WHY W HY WHY WHY WHY W HY WHY WHY WHY W HY WHY WHY WHY W HY WHY WHY WHY W
Slide 5
@zachleat
WHY WHY WHY WHY YWHY WHY WHY WHY WHY WHY WHY WHY WHY YWHY WHY WHY WHY WHY WHY WHY WHY WHY YWHY WHY WHY WHY WHY WHY WHY WHY WHY YWHY WHY WHY WHY WHY WHY WHY WHY WHY YWHY WHY WHY WHY WHY
Slide 6
Y THE 5Y OF WEB FONT Y LOADING Y PERFORMANCE Y
Slide 7
THE DEFAULT Wordpress Site
Slide 8
THE DEFAULT Wordpress Site
595 KB 35 requests
Slide 9
17% WEB Fonts 100 KB in 5 requests
YYYYY
48% Images, 8 requests 22% JavaScript, 12 requests 17% Fonts, 5 requests 12% CSS, 8 requests 1% HTML, 2 requests
Slide 10
Slide 11
YY
SANS SERIF BOLD
15.3 KB
Slide 12
Slide 13
YYYY 20.8 KB
SERIF ITALIC
Slide 14
YYYY Y 26.2 KB
SERIF BOLD
Slide 15
All demos on GitHub
https://github.com/zachleat/performance-sometime
Slide 16
https://www.webpagetest.org/
METHODOLOGY 3G Network Speed HTTP/2 and HTTPS CHROME & WOFF2 ONLY FONT OPTIMIZATIONS @zachleat
Slide 17
THE default Wordpress Site
SERIF SANS-SERIF BOLD SERIF BOLD SERIF ITALIC SANS-SERIF first render 3.3s
visually complete
5.7s
Slide 18
OUR OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
Slide 19
OUR OPPONENTS: INVISIBLE TEXT FOIT TEXT IN MOTION
Slide 20
@zachleat
https://twitter.com/jmuspratt/status/561239961924403200
Slide 21
OUR OPPONENTS: INVISIBLE TEXT TEXT IN MOTION FOUT
Slide 22
CRITICAL REQUEST CHAINS DOMCONTENTLOADED FIRST CONTENTFUL PAINT FIRST PAINT
PERFORMANCE METRICS
FIRST RENDER
VISUALLY COMPLETE SPEED INDEX ONLOAD TIME TO INTERACTIVE CPU IDLE
Slide 23
FIRST RENDER FIRST CONTENTFUL PAINT
Slide 24
FIRST MEANINGFUL PAINT Finally a metric that PROPERLY accounts for web fonts !
MEASURE using LIGHTHOUSE
Slide 25
OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
NEW METRIC:
ALL TEXT VISIBLE
Slide 26
THE default Wordpress Site ALL TEXT VISIBLE
first render 3.3s
”
4.9s
visually complete
5.7s
Slide 27
OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
NEW METRIC:
WEB FONT REFLOW COUNT * After first render
Slide 28
REFLOW COUNTER
0
@zachleat
Slide 29
REFLOW COUNTER
10
@zachleat
Slide 30
REFLOW COUNTER
21
@zachleat
Slide 31
REFLOW COUNTER
32
@zachleat
Slide 32
REFLOW COUNTER
43
@zachleat
Slide 33
REFLOW COUNTER
54
@zachleat
Slide 34
REFLOW COUNTER
65
@zachleat
Slide 35
RE F RE LO FLO W W RE F R L E RE FL OW FLO OW W
THE default Wordpress Site
first render 3.3s
visually complete
5.7s
Slide 36
OUR METRICS:
ALL TEXT VISIBLE WEB FONT REFLOW COUNT
Slide 37
Slide 38
YYYYY “WEB-SAFE”/SYSTEM/INSTALLED FONTS
Slide 39
YYYYY
System fonts
System Fonts: Baseline:
-6% 3.1s first render 3.3s
-10% 5.1s visually complete 5.7s
Slide 40
YYYYY System fonts
No network requests INSTANT RENDERING @zachleat
Slide 41
@zachleat
THANK YOU
@zachleat @zachleat.com
Slide 42
Slide 43
Slide 44
BEST VIEWED @zachleat
IN CHROME
Slide 45
@zachleat
https://github.com/alrra/browser-logos
Slide 46
Slide 47
THE default Wordpress Site
first render 3.3s
visually complete
5.7s
Slide 48
Slide 49
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 50
Slide 51
<link rel=’preconnect’ href=’https://fonts.gstatic.com’ crossorigin>
Slide 52
<!— CSS —> <link rel=’dns-prefetch’ href=’//fonts.googleapis.com’> <!— Fonts —> <link rel=’preconnect’ href=’https://fonts.gstatic.com’ crossorigin> <link rel=’alternate’ …> <link rel=’alternate’ …> <script>…</script> <script>…</script> <style>…</style> <link rel=’stylesheet’ …> <link rel=’stylesheet’ href=’ https://fonts.googleapis.com/css?family= Noto Sans:400italic,700italic,400,700| Noto Serif:400italic,700italic,400,700| Inconsolata:400,700&subset=latin,latin-ext’>
Slide 53
PRECONNECT ! WITHOUT
CSS
WITH
FONTS
@zachleat
Slide 54
Preconnect Browser SUPPORT
https://caniuse.com/#feat=link-rel-preconnect
Slide 55
PRECONNECT:
GREAT FOR CROSS-ORIGIN FONT REQUESTS @zachleat
Slide 56
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 57
YYYYY THIRD PARTY ▸ SELF HOSTING
Slide 58
YYYYY
SELF HOSTING BASE LINE ▼
”
Self Hosting: Baseline:
-6% 3.1s first render 3.3s
-1% 5.6s visually complete 5.7s
Slide 59
WHAT HAPPENED?
SUPER LONG TTFB’S NETWORK CONGESTION? BAD HTTP/2 prioritiZATION @zachleat
Read more: https://blog.cloudflare.com/http-2-prioritization-with-nginx/
Slide 60
@font-face { src: url(notosans.woff2) format(‘woff2’); } ▼ @font-face { src: url(https://performance-sometimeassets.netlify.com/notosans.woff2) format(‘woff2’); }
Slide 61
YYYYY
SELF HOSTING SELF HOST ▼
”
Self Hosting: Baseline:
-6% 3.1s first render 3.3s
-1% 5.6s visually complete 5.7s
Slide 62
YYYYY
SELF HOSTING
WITH A BIT OF SHARDING USING PRECONNECT
”
Self Host & Shard:
Baseline:
-6% 3.1s first render 3.3s
5.7s visually complete 5.7s
Slide 63
***DON’T DO THIS, PROBABLY SHARDING IS AN ANTI-PATTERN ON HTTP/2 @zachleat
Slide 64
“ ONE PERSON’S TRASH IS ANOTHER PERSON’S -PATTERN TREASURE” ” ANTI-PATTERN
Slide 65
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 66
Slide 67
@font-face { font-display: swap; }
Shows Fallback Font Immediately, RENDER WEB FONT WHENEVER @zachleat
Learn more: https://font-display.glitch.me/
Slide 68
@font-face { font-display: optional; }
RENDER WEB FONT ONLY IF CACHED @zachleat
Learn more: https://font-display.glitch.me/
Slide 69
font-display Browser SUPPORT
https://caniuse.com/#feat=css-font-rendering-controls
Slide 70
font-display Browser SUPPORT
https://caniuse.com/#feat=css-font-rendering-controls
Slide 71
font-display: swap -ish
@zachleat
Slide 72
@zachleat
WE NO LONGER NEED JavaScript to load a WEB FONT !
Slide 73
WE NO LONGER NEED JavaScript to load a WEB FONT *WITH VISIBLE FALLBACK TEXT
@zachleat
Slide 74
YYYYY
SELF HOSTING
WITH A BIT OF SHARDING USING PRECONNECT
BASE LINE ▼
AND Font-DISPLAY
”
New:
Baseline:
-3% 3.2s first render 3.3s
5.7s visually complete 5.7s
Slide 75
OUR OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
Slide 76
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 77
Slide 78
<link href=”https:// fonts.googleapis.com/css? family=Lobster&display=swap” rel=”stylesheet”>
https://www.zachleat.com/web/google-fonts-display/
Slide 79
”
GOOGLE FONTS CDN WITH Font-DISPLAY
SELF HOSTING
WITH A BIT OF SHARDING USING PRECONNECT
AND Font-DISPLAY
“
Slide 80
https://csswizardry.com/2019/05/self-host-your-static-assets/
@zachleat
Slide 81
Slide 82
<link rel=”preload” href=”notosans.woff2” as=”font” type=”font/woff2” crossorigin>
Slide 83
PRELOAD BROWSER SUPPORT
https://caniuse.com/#feat=link-rel-preload
Slide 84
YYYYY
SELF HOSTING
WITH A BIT OF SHARDING USING PRECONNECT
BASE LINE ▼
AND Font-DISPLAY AND PRELOAD
”
⏰ New:
3.3s
▲ 3% 5.9s
Baseline:
first render 3.3s
visually complete 5.7s
Slide 85
PRELOADING fonts FROM A DIFFERENT ORIGIN INCURS CONNECTION COSTS AT A BAD TIME ⚠ @zachleat
Slide 86
YYYYY
SELF HOSTING
WITH A BIT OF SHARDING AND Font-DISPLAY AND PRELOAD
BASE LINE ▼
”
& New:
Baseline:
▲ 15% 3.8s first render 3.3s
-1% 5.6s visually complete 5.7s
Slide 87
OVERUSE OF PRELOAD WILL COST YOU in FIRST RENDER TIME ⚠ @zachleat
Slide 88
PRELOAD
PRELOAD
FIRST RENDER
@zachleat
Slide 89
FIRST RENDER PRELOAD
PRELOAD
PRELOAD @zachleat
Slide 90
FIRST RENDER
PRELOAD
PRELOAD
@zachleat
PRELOAD
Slide 91
PRELOAD SOME, NOT ALL. HOW TO CHOOSE? @zachleat
Slide 92
Slide 93
PRIORIZATION STRATEGY:
USER DISRUPTION METRICS
@zachleat
Slide 94
Y
USER DISRUPTION
Y
Y Y Y
PRIORIZATION
YYYYY
Y Y Y
@zachleat
Y
Slide 95
What reflows are most likely to BE THE MOST DISRUPTIVE? @zachleat
Slide 96
Y
USER DISRUPTION
Y
Y Y Y
PRIORIZATION
YYYYY
Y Y Y
@zachleat
Y
Slide 97
METRICS
PRIORIZATION: PRELOAD ONE OF EACH FAMILY
@zachleat
YY YYY
Slide 98
Y
METRICS
PRIORIZATION: PRELOAD ONE OF EACH FAMILY
Y
Y
YY YYY Y
@zachleat
❤
Slide 99
ROMAN
FALLBACK
FAUX-BOLD
FONT-SYNTHESIS
❤
BOLD ( @zachleat
Slide 100
FONT-SYNTHESIS
FALLBACK
Y
@zachleat
)
Y
Slide 101
Slide 102
DEAR WEB BROWSERS, CAN YOU COPY WEBKIT Please? NON-WEBKIT
IT’S ME, MARGARET
❤
FONT-SYNTHESIS
Slide 103
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD & FONT-SYNTHESIS CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 104
Slide 105
OUR OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
Slide 106
RE F RE LO FLO W W RE F R L E RE FL OW FLO OW W
THE default Wordpress Site
first render 3.3s
visually complete
5.7s
Slide 107
PRELOAD EVERYTHING NO REFLOWS!
FIRST * RENDER
& New:
Baseline:
▲ 15% 3.8s first render 3.3s
-1% 5.6s visually complete 5.7s
Slide 108
R RE EFL FLO OW W RE FLO W
PRELOAD TWO FONTS ❤ FONT-SYNTHESIS
New:
3.3s
Baseline:
first render 3.3s
-1% 5.6s visually complete 5.7s
Slide 109
YYYYY CSS FONT LOADING API
Slide 110
LOAD A WEB FONT USING JS // Remove existing @font-face blocks // Make it let font = new FontFace( “Noto Serif”, “url(notoserif.woff2) format(‘woff2’)” ); // Load it let loadedFont = await font.load(); // Render it document.fonts.add(loadedFont); Full Code at https://github.com/zachleat/performance-sometime/blob/master/css-font-loading.js
Slide 111
LOAD TWO WEB FONTS USING JS
// Remove existing @font-face blocks // Make two let font = new FontFace(“Noto Serif”, /* … /); let fontBold = new FontFace(“Noto Serif”, / … */); // Load two let fonts = await Promise.all([ font.load(), fontBold.load() ]); // Render them at the same time!!! fonts.forEach(font => document.fonts.add(font));
Full Code at https://github.com/zachleat/performance-sometime/blob/master/css-font-loading.js
Slide 112
NO CHANGES TO CSS REQUIRED !
Slide 113
YYYYY
ON ER EF LO W
SELF HOSTING AND Font-DISPLAY AND PRELOAD: 2 of 5 AND SHARDING: 3 of 5 WITH PRECONNECT
AND CSS FONT LOADING: 3 of 5
New:
3.3s
5.7s
Baseline:
first render 3.3s
visually complete 5.7s
Slide 114
ROMAN
FALLBACK
FAUX-BOLD
FONT-SYNTHESIS
BOLD ( @zachleat
Slide 115
ROMAN
FONT-SYNTHESIS
FAUX-BOLD
BOLD ( @zachleat
❤
Slide 116
JavaScript FONTS CAN BE FANCY: NETWORK INFORMATION API Opt out of fonts on slow connections
https://developer.mozilla.org/en-US/docs/Web/API/Network_Information_API
Save-Data
Opt-out of fonts when the user has enabled Data Saver mode.
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/save-data/
PREFERS-REDUCED-MOTION
https://webkit.org/blog/7551/responsive-design-for-motion/#using-reduce-motion-on-the-web
@zachleat
Opt-out of font reflows when the user has enabled Reduce Motion in accessibility preferences.
Slide 117
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 118
Slide 119
Slide 120
https://www.axis-praxis.org/
https://www.preusstype.com
Slide 121
YYYY Y 15.3KB 15.4KB
22.9KB
20.9KB
26.4KB
100.9KB
Slide 122
Y Y
100.0KB
CompressaPRO-GX.woff2 Read more about Variable Font size comparisons: http://stuff.djr.com/gimlet-vf-size-test/
Slide 123
YYYYY
SELF HOSTING WITH A SINGLE 115KB VARIABLE FONT
BASE LINE ▼
”
New:
Baseline:
first render 3.3s
visually complete 5.7s
Slide 124
YYYYY
SELF HOSTING WITH A SINGLE 115KB VARIABLE FONT
”
New:
Baseline:
first render 3.3s
visually complete 5.7s
Slide 125
YYYYY
SELF HOSTING WITH A SINGLE 115KB VARIABLE FONT
W LO EF ER ON
New:
Baseline:
first render 3.3s
visually complete 5.7s
Slide 126
v-fonts.com
Region 1 ntitled 2 ntitled 5 ntitled 8 titled 11 titled 14 titled 17 titled 20 titled 23 0
75
150
225
69.3 KB mean 54.1 KB Median
300
Slide 127
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 128
YYYYY
SELF HOSTING AND Font-DISPLAY AND PRELOAD: 2 of 5 AND SHARDING: 3 of 5 WITH PRECONNECT
AND CSS FONT LOADING: 3 of 5
New:
3.3s
5.7s
Baseline:
first render 3.3s
visually complete 5.7s
Slide 129
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 130
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 131
OUR TOOLS: WOFF2 PRECONNECT SELF HOSTING SHARDING #
FONT-DISPLAY PRELOAD CSS FONT LOADING API SUBSETTING VARIABLE FONTS
Slide 132
OUR OPPONENTS: INVISIBLE TEXT TEXT IN MOTION
-ISH
Slide 133
All demos on GitHub
https://github.com/zachleat/performance-sometime
Slide 134
@zachleat
A COMPREHENSIVE GUIDE TO
FONT LOADING
STRATEGIES zachleat.com/web/comprehensive-webfonts/ 55 (and counting) font loading posts at zachleat.com/web/fonts/ Web Font Loading Recipes
https://github.com/zachleat/web-font-loading-recipes
Slide 135
Slide 136
@zachleat
THANK YOU
@zachleat @zachleat.com