Slide 1

Slide 1 text

@onishiweb Best viewed with… Adam Onishi Velocity Conf Amsterdam - October 2015

Slide 2

Slide 2 text

@onishiweb A long time ago…

Slide 3

Slide 3 text

@onishiweb @onishiweb

Slide 4

Slide 4 text

@onishiweb

Slide 5

Slide 5 text

@onishiweb “Browser wars!”

Slide 6

Slide 6 text

@onishiweb @onishiweb

Slide 7

Slide 7 text

@onishiweb – a website in 2015 “Oops. Your browser is no longer supported”

Slide 8

Slide 8 text

@onishiweb Chrome Firefox IE Safari Opera UC Browser Safari (iOS) Opera Mini Android Browser Amazon Silk YaBrowser Maxthon Iron Nokia Browser Sea Monkey Avant Camino Epiphany OmniWeb Konqueror Galeon Swiftfox Edge

Slide 9

Slide 9 text

@onishiweb Chrome (v46) • Cache.addAll() • HTTP Client hints • CSS.escape() Edge • img srcset • CSS Regions • Arrow functions Firefox (v41) • Font Loading API • Cache API • Cut/Copy web API Safari (v9) • Backdrop filters • CSS scroll snapping • Content blocking

Slide 10

Slide 10 text

@onishiweb

Slide 11

Slide 11 text

@onishiweb A moratorium http://www.quirksmode.org/blog/archives/2015/07/stop_pushing_th.html

Slide 12

Slide 12 text

@onishiweb Developer-first development

Slide 13

Slide 13 text

@onishiweb Cake or Death?

Slide 14

Slide 14 text

@onishiweb Progressive enhancement

Slide 15

Slide 15 text

@onishiweb “Vague, but exciting”

Slide 16

Slide 16 text

@onishiweb The Web JS CSS HTML Internet

Slide 17

Slide 17 text

@onishiweb Chrome Firefox IE Safari Opera UC Browser Safari (iOS) Opera Mini Android Browser Amazon Silk YaBrowser Maxthon Iron Nokia Browser Sea Monkey Avant Camino Epiphany OmniWeb Konqueror Galeon Swiftfox Edge

Slide 18

Slide 18 text

@onishiweb – Paul Robert Lloyd “By making fewer assumptions about context and interface, focusing more on users’ tasks and goals, we can create more adaptable products.” http://alistapart.com/article/thinking-responsively-a-framework-for-future-learning

Slide 19

Slide 19 text

@onishiweb Photo from EdgeConf 2015 @onishiweb

Slide 20

Slide 20 text

@onishiweb

Slide 21

Slide 21 text

@onishiweb Control

Slide 22

Slide 22 text

@onishiweb Defensive design

Slide 23

Slide 23 text

@onishiweb What we do know

Slide 24

Slide 24 text

@onishiweb Baseline

Slide 25

Slide 25 text

@onishiweb Performance

Slide 26

Slide 26 text

@onishiweb Performance Perceived

Slide 27

Slide 27 text

@onishiweb

Slide 28

Slide 28 text

@onishiweb

Slide 29

Slide 29 text

@onishiweb Progressively enhanced performance

Slide 30

Slide 30 text

@onishiweb https://github.com/onishiweb/progressive-performance

Slide 31

Slide 31 text

@onishiweb Render blocking assets

Slide 32

Slide 32 text

@onishiweb CSS, Fonts, and JavaScript

Slide 33

Slide 33 text

@onishiweb Browser rendering

Slide 34

Slide 34 text

@onishiweb Stuff Request Render DNS Lookup Initial connection SSL Negotiation Time to first byte (TTFB) Content download

Slide 35

Slide 35 text

@onishiweb Stuff Request Render Stuff Stuff Stuff Stuff Stuff Stuff

Slide 36

Slide 36 text

@onishiweb CSS

Slide 37

Slide 37 text

@onishiweb CSS is still an enhancement

Slide 38

Slide 38 text

@onishiweb CSS as an enhancement

Slide 39

Slide 39 text

@onishiweb Critical Path CSS

Slide 40

Slide 40 text

@onishiweb Tooling

Slide 41

Slide 41 text

@onishiweb “Set it. Forget it.” – Tim Kadlec https://speakerdeck.com/tkadlec/reaching-everyone-fast-at-from-the-front-2015?slide=75

Slide 42

Slide 42 text

@onishiweb https://github.com/addyosmani/critical

Slide 43

Slide 43 text

@onishiweb https://github.com/pocketjoso/penthouse

Slide 44

Slide 44 text

@onishiweb gulp.task('critical', function () { penthouse({ url : 'http://localhost:4444/index.html', css : 'public/styles.css', width : 720, // viewport width height : 500 // viewport height }, function(err, criticalCss) { if (err) { // handle error } fs.writeFileSync('public/critical.css', criticalCss); }); });

Slide 45

Slide 45 text

@onishiweb loadCSS https://github.com/filamentgroup/loadCSS/

Slide 46

Slide 46 text

@onishiweb function loadCSS(e,t,n) { ... } loadCSS('/css/main.min.css');

Slide 47

Slide 47 text

@onishiweb rel="preload" https://github.com/filamentgroup/loadCSS/issues/59

Slide 48

Slide 48 text

@onishiweb function loadCSS(e,t,n) { ... } function preloadSupported() { ... } if( ! preloadSupported() ){ loadCSS( asyncCSS.href ); }

Slide 49

Slide 49 text

@onishiweb Cache locally

Slide 50

Slide 50 text

@onishiweb Progressively enhancing CSS delivery

Slide 51

Slide 51 text

@onishiweb Fonts

Slide 52

Slide 52 text

@onishiweb We ❤ web fonts

Slide 53

Slide 53 text

@onishiweb

Slide 54

Slide 54 text

@onishiweb

Slide 55

Slide 55 text

@onishiweb 3s 3s 3s ∞ -

Slide 56

Slide 56 text

@onishiweb Asynchronous font loading

Slide 57

Slide 57 text

@onishiweb Font loading API

Slide 58

Slide 58 text

@onishiweb FOUT FOIT

Slide 59

Slide 59 text

@onishiweb Flash Of Unstyled Text Flash Of Invisible Text

Slide 60

Slide 60 text

@onishiweb FOUT vs FOIT

Slide 61

Slide 61 text

@onishiweb Control over fonts

Slide 62

Slide 62 text

@onishiweb var newFont = new FontFace("open_sansbold", "url(/fonts/ opensans-bold-webfont.woff)", {}); newFont.load().then(function (loadedFace) { document.fonts.add(loadedFace); document.body.style.fontFamily = "open_sansbold, serif"; });

Slide 63

Slide 63 text

@onishiweb document.fonts.ready.then(function() { var content = document.getElementById("content"); content.style.visibility = "visible"; });

Slide 64

Slide 64 text

@onishiweb CSS Font Rendering https://tabatkins.github.io/specs/css-font-display/

Slide 65

Slide 65 text

@onishiweb @font-face { font-family: 'Graublau Web'; src: url('GraublauWeb.woff'); font-display: swap; }

Slide 66

Slide 66 text

@onishiweb font-display: auto | block | swap | fallback | optional;

Slide 67

Slide 67 text

@onishiweb Font loading API http://caniuse.com/#feat=font-loading 41 43 31 ❌

Slide 68

Slide 68 text

@onishiweb Font display ❌ ❌ ❌ ❌

Slide 69

Slide 69 text

@onishiweb Progressively enhancing font loading

Slide 70

Slide 70 text

@onishiweb JavaScript

Slide 71

Slide 71 text

@onishiweb @onishiweb

Slide 72

Slide 72 text

@onishiweb @onishiweb

Slide 73

Slide 73 text

@onishiweb – Peter Herlihy, GDS Team “1.1% of people aren’t getting JavaScript enhancements (1 in 93).”

Slide 74

Slide 74 text

@onishiweb http://kryogenix.org/code/browser/everyonehasjs.html

Slide 75

Slide 75 text

@onishiweb

Slide 76

Slide 76 text

@onishiweb – Jeremy Keith “Brilliant easter egg in the newly- redesigned nasa.gov — if JavaScript fails, you are immersed in the experience of deep space”

Slide 77

Slide 77 text

@onishiweb Frameworks

Slide 78

Slide 78 text

@onishiweb – Jake Archibald “Nothing should have a JavaScript dependant first render, it only punishes the user.”

Slide 79

Slide 79 text

@onishiweb Is there a better way?

Slide 80

Slide 80 text

@onishiweb Universal JavaScript

Slide 81

Slide 81 text

@onishiweb Server Side rendering with Node.js

Slide 82

Slide 82 text

@onishiweb React

Slide 83

Slide 83 text

@onishiweb React.renderToString();

Slide 84

Slide 84 text

@onishiweb app.get('/', function(req, res){ // React.renderToString takes your component // and generates the markup ReactApp = React.createFactory( require('../components/ index.js') ); reactHtml = React.renderToString( ReactApp({}) ); // Output html rendered by react res.render('index.ejs', { reactOutput: reactHtml }); });

Slide 85

Slide 85 text

@onishiweb Client side too

Slide 86

Slide 86 text

@onishiweb GoCardless

Slide 87

Slide 87 text

@onishiweb – Jack Franklin, GoCardless “If you visit it in a ‘good’ browser with JS on, you get an incredibly snappy React app, if not, you hit the server on every click.”

Slide 88

Slide 88 text

@onishiweb Progressively enhancing JavaScript frameworks

Slide 89

Slide 89 text

@onishiweb Control

Slide 90

Slide 90 text

@onishiweb @onishiweb

Slide 91

Slide 91 text

@onishiweb Render blocking assets

Slide 92

Slide 92 text

@onishiweb Stuff Request Render Stuff Stuff Stuff Stuff Stuff Stuff

Slide 93

Slide 93 text

@onishiweb Stuff Request Render

Slide 94

Slide 94 text

@onishiweb The Network

Slide 95

Slide 95 text

@onishiweb The Web JS CSS HTML Internet

Slide 96

Slide 96 text

@onishiweb Stuff Request Render Network

Slide 97

Slide 97 text

@onishiweb Assumption

Slide 98

Slide 98 text

@onishiweb @onishiweb

Slide 99

Slide 99 text

@onishiweb Mobile connectivity

Slide 100

Slide 100 text

@onishiweb Cake or Death?

Slide 101

Slide 101 text

@onishiweb Enter ServiceWorker

Slide 102

Slide 102 text

@onishiweb – Nicolas Bevacqua “…everything seems to point at ServiceWorker being the most significant addition to the web platform since the introduction of AJAX – over 10 years ago” https://ponyfoo.com/articles/serviceworker-revolution

Slide 103

Slide 103 text

@onishiweb Web vs Native!

Slide 104

Slide 104 text

@onishiweb The web is going offline!

Slide 105

Slide 105 text

@onishiweb Browser cache

Slide 106

Slide 106 text

@onishiweb @onishiweb

Slide 107

Slide 107 text

@onishiweb Cache content Register SW Stuff Request Render

Slide 108

Slide 108 text

@onishiweb Cache Stuff Request Render SW

Slide 109

Slide 109 text

@onishiweb if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/worker.js') .then(function(registration) { // Registration was successful console.log('SW registered: ', registration.scope); }) .catch(function(err) { // registration failed :( console.log('SW registration failed: ', err); }); }

Slide 110

Slide 110 text

@onishiweb self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open('content-cache-v1') .then(function(cache) { return cache.addAll([ '/index.html', '/css/main.min.css', '/main.js' ]); }) ) });

Slide 111

Slide 111 text

@onishiweb self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { console.log('Return from cache now', event.request); // Cache hit - return response if (response) { return response; } return fetch(event.request); } ) ); });

Slide 112

Slide 112 text

@onishiweb

Slide 113

Slide 113 text

@onishiweb Cache, falling back to network

Slide 114

Slide 114 text

@onishiweb Stale content

Slide 115

Slide 115 text

@onishiweb Cache Network Stuff Request Render SW Send notification Webpage @onishiweb

Slide 116

Slide 116 text

@onishiweb Cache then network https://ponyfoo.com/articles/progressive-networking-serviceworker

Slide 117

Slide 117 text

@onishiweb Twitter screenshot

Slide 118

Slide 118 text

@onishiweb https://jakearchibald.com/2014/offline-cookbook/

Slide 119

Slide 119 text

@onishiweb Diving in head first…

Slide 120

Slide 120 text

@onishiweb Development flow https://www.chromium.org/blink/serviceworker/getting-started#TOC-Development-flow

Slide 121

Slide 121 text

@onishiweb https://code.google.com/p/chromium/issues/detail?id=500428#c10

Slide 122

Slide 122 text

@onishiweb chrome://inspect/#service-workers

Slide 123

Slide 123 text

@onishiweb New Service Worker inspector - Jake’s Tweet @onishiweb https://twitter.com/jaffathecake/status/656034298148048896

Slide 124

Slide 124 text

@onishiweb HTTPS only

Slide 125

Slide 125 text

@onishiweb – MDN “Having modified network requests wide open to man in the middle attacks would be really bad.”

Slide 126

Slide 126 text

@onishiweb How much can I cache?

Slide 127

Slide 127 text

@onishiweb Browser support…

Slide 128

Slide 128 text

@onishiweb ServiceWorker https://jakearchibald.github.io/isserviceworkerready/ 44 40 24 ❌ ❌

Slide 129

Slide 129 text

@onishiweb Fetch https://jakearchibald.github.io/isserviceworkerready/ 39 40 27 ❌ ❌

Slide 130

Slide 130 text

@onishiweb Cache API https://jakearchibald.github.io/isserviceworkerready/ 41 46 33 ❌ ❌

Slide 131

Slide 131 text

@onishiweb https://jakearchibald.github.io/isserviceworkerready/

Slide 132

Slide 132 text

@onishiweb Progressively enhancing the network

Slide 133

Slide 133 text

@onishiweb Return of the “browser wars”

Slide 134

Slide 134 text

@onishiweb Not really

Slide 135

Slide 135 text

@onishiweb Stop assuming

Slide 136

Slide 136 text

@onishiweb – Bruce Lawson “It never pays to make too many assumptions about your users.”

Slide 137

Slide 137 text

@onishiweb Be defensive

Slide 138

Slide 138 text

@onishiweb Improve performance

Slide 139

Slide 139 text

@onishiweb Critical Path CSS

Slide 140

Slide 140 text

@onishiweb Critical Path CSS Font Loading API

Slide 141

Slide 141 text

@onishiweb Critical Path CSS Font Loading API Universal JavaScript

Slide 142

Slide 142 text

@onishiweb Critical Path CSS Font Loading API Universal JavaScript ServiceWorker

Slide 143

Slide 143 text

@onishiweb – Tim Kadlec “Growing divide between what the web is capable of & its power (universal access) makes progressive enhancement more important than ever—not less”

Slide 144

Slide 144 text

@onishiweb Thanks Adam Onishi Velocity Conf Amsterdam - October 2015

Slide 145

Slide 145 text

@onishiweb Questions?