Slide 1

Slide 1 text

Improving Web Fonts Performance Vitaly Friedman 05/06/2015 • Faenza, Italy

Slide 2

Slide 2 text

Vitaly Friedman, editor-in-chief
 and co-founder of SmashingMag

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

A Little Story

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Ilya Grigorik,“Resilient Networking: Planning for Failure”, https://www.igvita.com/2015/01/26/resilient-networking/

Slide 16

Slide 16 text

“Many people in the design process simply don’t know a lot about of performance consequences of their design decisions.
 — Brad Frost

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

• T-Mobile roaming charges for loading the
 full front page of Vogue.co.uk, in Moscow: €93,13

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

“There is no difference for the user between a site being down and a site being inaccessible due to loading issues caused by blocking resources or slow networks. 
 — Andy Hume
 “Real-Life Responsive Redesign”, SmashingConf 2013

Slide 23

Slide 23 text

State of Font Loading

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Web Fonts Dilemma • The choice of formats depends on browser support: • WOFF (Web Open Font Format) • TTF (TrueType) • OTF (OpenType) • EOT (Embedded OpenType) • SVG Fonts (Scalable Vector Graphics) • WOFF2 (Web Open Font Format 2)

Slide 29

Slide 29 text

Web Fonts Dilemma • WOFF2 has the best compression, but isn’t supported by older Android/iOS. WOFF is. • Old Android and iOS support TTF and OTF; Internet Explorer 6–8 needs EOT. • SVG doesn’t support OpenType features. 
 Not supported in IE, Chrome or Firefox.

Slide 30

Slide 30 text

Web Fonts Dilemma • WOFF2 supported by older Android/iOS. • Old Android and iOS support Internet Explorer 6–8 needs • SVG doesn’t support OpenType features. Supported in Chrome, Safari, Opera. • Strategy: WOFF/2 with TTF/OTF and EOT for IE 6–8; not SVG. Best compression always wins.

Slide 31

Slide 31 text

Declaring @font-face • We can use bulletproof @font-face syntax to avoid common traps along the way: • CSS:
 @font-face { 
 font-family: 'Elena Regular'; 
 src: url('elena.eot?#iefix') format('embedded-opentype'),
 url('elena.woff2') format('woff2'),
 url('elena.woff') format('woff'),
 url('elena.otf') format('opentype');
 }

Slide 32

Slide 32 text

Declaring @font-face • If you want only smart browsers (IE9+) to download fonts, declaration can be shorter: • CSS:
 @font-face { 
 font-family: 'Elena Regular'; 
 src: url('elena.woff2') format('woff2'),
 url('elena.woff') format('woff'),
 url('elena.otf') format('opentype');
 }

Slide 33

Slide 33 text

• CSS:
 @font-face { 
 font-family: 'Elena Regular'; 
 src: url('elena.woff2') format('woff2'),
 url('elena.woff') format('woff'),
 url('elena.otf') format('opentype');
 } • When a font family name is used in CSS, browsers match it against all @font-face rules, download web fonts, display content.

Slide 34

Slide 34 text

• When a font family name is used in CSS, browsers match it against all @font-face rules, download web fonts, display content. • CSS:
 body { 
 font-family: 'Skolar Regular',
 AvenirNext, Avenir, /* iOS */
 'Roboto Slab', 'Droid Serif', /* Android */
 'Segoe UI', /* Microsoft */ 
 Georgia, 'Times New Roman', serif; /* Fallback */
 }

Slide 35

Slide 35 text

• CSS:
 body { 
 font-family: 'Skolar Regular',
 AvenirNext, Avenir, /* iOS */
 'Roboto Slab', 'Droid Serif', /* Android */
 'Segoe UI', /* Microsoft */ 
 Georgia, 'Times New Roman', serif; /* Fallback */
 } • HTML:
 
 
 
 
 try{Typekit.load();}catch(e){}

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

• Once DOM and CSSOM are constructed, if @font-face matches, a font will be required. • If fonts aren’t cached yet, they will be requested, downloaded and applied, deferring rendering.

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

• FOUT (Flash Of Unstyled Text): show content in fallback fonts first, then switch to web fonts. • FOIT (Flash Of Invisible Text): no content displayed until the font becomes available.

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Web Fonts Rendering • If we request fonts directly, users might
 be getting a FOIT, then FOUT, then web fonts. • Solution: prioritize content over presentation. Display content right away, swap fonts later:

Slide 42

Slide 42 text

Web Fonts Rendering • Solution: prioritize content over presentation. Display content right away, swap fonts later: • First visit: show content in fallback fonts fast, • Apply web fonts right away, or on later visits, • Load web fonts async during rendering, • Cache web fonts properly (opt. localStorage), • Next visits: apply web fonts only if they’re cached.

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

The Guardian Redesign (2013) • Project goals focused on mobile experience: • Tackle dropping print circulation with mobile, • Replace the slow, rigid mobile/desktop sites, • Solution: a mobile-first “stealth” redesign with a strong focus on progressive enhancement. • First focus on “mobile” experience, • Long term: new RWD client-side architecture, • Ultimate goal: one code base, one responsive site.

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

The Guardian Redesign • Priority lists for content and styles to define “core”: • Core content doesn’t rely on JavaScript, • Only one main feature image considered “core”, • No Ajax support for ratings, comments and live scores, • “Cutting the mustard” to “buckle” browsers, • Web fonts aren’t loaded by default (prevent FOUT).

Slide 47

Slide 47 text

The Guardian’s Modular Load • Consider at least three types of page content: • Core content
 (essential HTML+CSS, usable non-JS enhanced experience); • Enhancement
 (JS, Geolocation, touch, enhanced CSS, Web fonts, widgets); • Leftovers
 (analytics, advertising, third-party content). • Idea: load Core content first, then Enhancement on DOMContentLoaded, then Leftovers on Load.

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

The Guardian’s Modular Load • Load JS into a browser asynchronously.
 While JS is being downloaded, browser still
 can parse the document and show content. • HTML/JS (for modern browsers):
 @if(isModernBrowser) {
 
 }

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

BBC’s isModernBrowser( ) • We can use server-side device detection using UA strings with DeviceAtlas, WURFL etc. • We can use client-side feature detection to split browsers into groups “HTML4” / “HTML5”. • JS:
 if (
 'querySelector' in document &&
 'localStorage' in window &&
 'addEventListener' in window ) {
 // HTML5 browser detected; load the JS app
 }


Slide 52

Slide 52 text

BBC’s isModernBrowser( ) • JS:
 if (
 'querySelector' in document &&
 'localStorage' in window &&
 'addEventListener' in window ) {
 // HTML5 browser detected; load the JS app
 }
 • HTML5 Browsers:
 IE9+, FF 3.5+, Opera 9+,
 Safari 4+, Chrome 1+, iOS1+,
 Android phone and tablets 2.1+,
 Blackberry OS6+, Win 7.5+,
 Mobile Firefox, Opera Mobile • HTML4 Browsers:
 IE8-, Blackberry OS5-,
 Nokia S60 v6-, Nokia S40,
 Symbian, Windows 7 Phone (pre-Mango), a plethora of legacy devices.

Slide 53

Slide 53 text

BBC’s isModernBrowser( ) • JS:
 if ('visibilityState' in document) {
 // HTML5 browser detected; load the JS app
 }
 • HTML5 Browsers:
 IE9+, FF 3.5+, Opera 9+,
 Safari 4+, Chrome 1+, iOS1+,
 Android phone and tablets 2.1+,
 Blackberry OS6+, Win 7.5+,
 Mobile Firefox, Opera Mobile • HTML4 Browsers:
 IE8-, Blackberry OS5-,
 Nokia S60 v6-, Nokia S40,
 Symbian, Windows 7 Phone (pre-Mango), a plethora of legacy devices.

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

SmashingMag’s Modular Load • Consider three types of page content: • Core content
 (essential HTML+CSS, usable non-JS enhanced experience); • Enhancement
 (JS, syntax highlighter, full CSS, Web fonts, comments); • Leftovers
 (analytics, advertising, Gravatar images). • Idea: load Core content first, then Enhancement on DOMContentReady, then Leftovers on Load.

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

SmashingMag’s Optimization • Minor optimizations based on a simple principle: optimize content, defer the rest. • Load critical CSS inline and full CSS on load, • Avoid JavaScript libraries (jQuery → JavaScript), • Store Web fonts in localStorage + cookies, • Defer advertising, tracking and all non-critical CSS/JS, • Replaced Respond.js with IE8 stylesheet (fixed-width). • Optimize the critical rendering path for content delivery.

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

Smart CSS Font Fallback • With font delivery services, Web Font Loader gives you a granular control over font loading. • HTML/CSS:
 
 
 .wf-loading // fonts start to load
 .wf-active // all (or some) fonts have loaded
 .wf-inactive // all fonts failed to load


Slide 76

Slide 76 text

Smart CSS Font Fallback • We can also use CSS to tweak font fallback metrics to reduce the jump between the default font and the Web font... • ...and add sensible “mobile” OS fonts into a fallback font stack and adjust their styling. • iOS 6.1:
 Avenir, Avenir Next Condensed, Baskerville, Helvetica, Hoefler Text, Palatino, Optima. • Win Phone 7:
 Calibri, Cambria & Co., Georgia, Segoe UI, Lucida Grande, Lucida Sans Unicode.

Slide 77

Slide 77 text

Smart CSS Font Fallback • We can also use CSS to tweak font fallback metrics to reduce the jump between the default font and the Web font... • ...and add sensible “mobile” OS fonts into a fallback font stack and adjust their styling. • Android 4:
 Droid Sans, Droid Sans Mono, Droid Serif, Roboto. • Win Phone 7:
 Calibri, Cambria & Co., Georgia, Segoe UI, Lucida Grande, Lucida Sans Unicode.

Slide 78

Slide 78 text

Smart CSS Font Fallback • ...and add sensible “mobile” OS fonts into a fallback font stack and adjust their styling. • CSS:
 .wf-loading h1 {
 font-family:
 'Tablet Gothic Condensed',
 'HelveticaNeue-CondensedBlack',
 'Helvetica Neue',
 'Segoe UI', 'Roboto', sans-serif;
 font-weight: 800;
 font-stretch: condensed;
 }


Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

Dealing With Faux Fonts • If browsers find a match for family name, but not the required variation (e.g. bold), they will attempt to generate the required variation. • Solution: use unique font-family names, and set
 styles to match those in @font-face declarations.

Slide 81

Slide 81 text

• CSS:
 .elena-reg {
 font-family: 'Elena Regular', sans-serif;
 font-weight: 400;
 font-style: normal;
 }
 .elena-italic {
 font-family: 'Elena Italic', sans-serif;
 font-weight: 400;
 font-style: italic;
 }
 .elena-bold {
 font-family: 'Elena Bold', sans-serif;
 font-weight: 700;
 font-style: normal;
 }
 • Solution: use unique font-family names, and set
 styles to match those in @font-face declarations.

Slide 82

Slide 82 text

• CSS:
 strong {
 font-family: 'Elena Bold', sans-serif;
 font-weight: 700;
 font-style: normal;
 }
 em {
 font-family: 'Elena Italic', sans-serif;
 font-weight: 400;
 font-style: italic;
 }
 em.light {
 font-family: 'Elena Light Italic', sans-serif;
 font-weight: 300;
 font-style: italic;
 }
 • Solution: use unique font-family names, and set
 styles to match those in @font-face declarations.

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

“SmashingMag is the only site I can read on an EDGE connection when commuting in São Paulo, every day. It makes me think why other sites aren’t optimizing for slow connections, too. 
 — a reader from Brazil

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

CSS Font Loading API • Native browser API à la Web Font Loader, with a 
 FontFace object representing @font-face rules. • JavaScript:
 var elena_reg = new FontFace(
 'Elena Regular',
 'url(elena_reg.woff) format("woff"),' + 
 'url(elena_reg.otf) format("otf")', 
 { weight: 'regular', unicodeRange: 'U+0-7ff' } 
 );

Slide 88

Slide 88 text

• JavaScript:
 document.fonts.load('1em elena_reg')
 .then(function() {
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-loaded';
 }).catch(function () { 
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-failed';
 }); • JavaScript:
 var elena_reg = new FontFace(
 'Elena Regular',
 'url(elena_reg.woff) format("woff"),' + 
 'url(elena_reg.otf) format("otf")', 
 { weight: 'regular', unicodeRange: 'U+0-7ff' } 
 );

Slide 89

Slide 89 text

• JavaScript:
 document.fonts.load('1em elena_reg')
 .then(function() {
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-loaded';
 }).catch(function () { 
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-failed';
 }); • CSS:
 .elena_reg-loaded h1 {
 font-family: "Elena Regular";
 }

Slide 90

Slide 90 text

• JavaScript:
 document.fonts.load('1em elena_reg’)
 .then(function() {
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-loaded’;
 }).catch(function () { 
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-failed’;
 }); • CSS:
 .elena_reg-loaded h1 {
 font-family: "Elena Regular";
 font-rendering: "block 0s swap infinite"; // FOUT
 // font-rendering: "block 3s swap infinite"; // FOIT
 }

Slide 91

Slide 91 text

• JavaScript:
 document.fonts.load('1em elena_reg’)
 .then(function() {
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-loaded’;
 }).catch(function () { 
 var docEl = document.documentElement;
 docEl.className += ' elena_reg-failed’;
 }); • CSS:
 .elena_reg-loaded h1 {
 font-family: "Elena Regular";
 // font-rendering: "block 0s swap infinite"; // FOUT
 font-rendering: "block 3s swap 3s"; // FOIT, at most 3sec
 }

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

No content

Slide 95

Slide 95 text

No content

Slide 96

Slide 96 text

Performance Strategy • Use subsetting to minimize font’s size, • Support WOFF/2, OTF/TTF and EOT, • When embedding web fonts, use either
 localStorage or CSS Font Loading API, • When using font delivery services, use
 Web Font Loader to load fonts async, Treat web fonts as progressive enhancement: 3. Thorough planning pays off in long term, 4. Design components in Photoshop desktop first, 5. Build mobile first = commitment to the content, 6. Quick prototypes in the browser asap, • Defer fonts loading, show fallback fonts first. • Consider smart CSS font stacks with OS fonts, • Avoid faux bold/italic with exact CSS definitions,

Slide 97

Slide 97 text

Thank you.

Slide 98

Slide 98 text

Image credits • Front cover: Geometric Wallpapers
 by Simon C Page (http://simoncpage.co.uk/ blog/2012/03/ipad-hd-retina-wallpaper/) • Beautiful maps: http://mapsdesign.tumblr.com • Sections illustrations: “bisous les copains”, by Guillaume Kurkdjian (http:// bisouslescopains.tumblr.com/)
 • Thanks to Tim Kadlec, Bram Stein, Andy Hume and Zach Leatherman’s research used in this talk.