Slide 1

Slide 1 text

@onishiweb Best viewed with… Adam Onishi State of the Browser - September 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 “For best results view this page in Chrome.”

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 (v44) - Cache.add() - Request.context() - Notification.data Edge - img srcset - CSS Regions - Arrow functions Firefox (v40) - Improved Dev tools - IndexedDB transactions - Fetch API (v39) 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 Photo by Simon Collison - https://flic.kr/p/pbRdFm @onishiweb

Slide 17

Slide 17 text

@onishiweb Photo by Pedro Ribeiro Simões - https://flic.kr/p/bvCA8 @onishiweb

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 @onishiweb

Slide 20

Slide 20 text

@onishiweb Control

Slide 21

Slide 21 text

@onishiweb Defensive design

Slide 22

Slide 22 text

@onishiweb What we do know

Slide 23

Slide 23 text

@onishiweb Baseline

Slide 24

Slide 24 text

@onishiweb Performance

Slide 25

Slide 25 text

@onishiweb Perceived Performance

Slide 26

Slide 26 text

@onishiweb

Slide 27

Slide 27 text

@onishiweb

Slide 28

Slide 28 text

@onishiweb Progressively enhanced performance

Slide 29

Slide 29 text

@onishiweb Render blocking assets

Slide 30

Slide 30 text

@onishiweb CSS, JS, & Fonts

Slide 31

Slide 31 text

@onishiweb CSS

Slide 32

Slide 32 text

@onishiweb CSS is still an enhancement

Slide 33

Slide 33 text

@onishiweb CSS as an enhancement

Slide 34

Slide 34 text

@onishiweb Critical Path CSS

Slide 35

Slide 35 text

@onishiweb Tooling

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

@onishiweb Progressively enhancing CSS delivery

Slide 40

Slide 40 text

@onishiweb Fonts

Slide 41

Slide 41 text

@onishiweb We ❤ web fonts

Slide 42

Slide 42 text

@onishiweb

Slide 43

Slide 43 text

@onishiweb

Slide 44

Slide 44 text

@onishiweb 3s 3s 3s ∞ -

Slide 45

Slide 45 text

@onishiweb Asynchronous font loading

Slide 46

Slide 46 text

@onishiweb Font loading API

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

@onishiweb var f = new FontFace("open_sansbold", "url(/fonts/ opensans-bold-webfont.woff)", {}); f.load().then(function (loadedFace) { document.body.className += ' fonts—loaded'; }); /* CSS */ p { visibility: hidden; } .fonts-loaded p { visibility: visible; }

Slide 49

Slide 49 text

@onishiweb Progressively enhancing font loading

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

@onishiweb CSS Font Rendering http://tabatkins.github.io/specs/css-font-rendering/

Slide 52

Slide 52 text

@onishiweb JavaScript

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

@onishiweb

Slide 56

Slide 56 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 57

Slide 57 text

@onishiweb Frameworks

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

@onishiweb Is there a better way?

Slide 60

Slide 60 text

@onishiweb Universal JavaScript

Slide 61

Slide 61 text

@onishiweb Server Side rendering with Node.js

Slide 62

Slide 62 text

@onishiweb React

Slide 63

Slide 63 text

@onishiweb React.renderToString();

Slide 64

Slide 64 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 65

Slide 65 text

@onishiweb Client side too

Slide 66

Slide 66 text

@onishiweb GoCardless

Slide 67

Slide 67 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 68

Slide 68 text

@onishiweb Progressively enhancing JavaScript frameworks

Slide 69

Slide 69 text

@onishiweb Control

Slide 70

Slide 70 text

@onishiweb The Network

Slide 71

Slide 71 text

@onishiweb Assumption

Slide 72

Slide 72 text

@onishiweb @onishiweb Photo by Paul Robertson - https://flic.kr/p/9qSizG

Slide 73

Slide 73 text

@onishiweb Mobile connectivity

Slide 74

Slide 74 text

@onishiweb Cake or Death?

Slide 75

Slide 75 text

@onishiweb Enter Service Worker

Slide 76

Slide 76 text

@onishiweb Web vs Native!

Slide 77

Slide 77 text

@onishiweb The web is going offline!

Slide 78

Slide 78 text

@onishiweb Browser cache

Slide 79

Slide 79 text

@onishiweb @onishiweb

Slide 80

Slide 80 text

@onishiweb Register service worker Cache content Response Request Render Usable website

Slide 81

Slide 81 text

@onishiweb Cache Request Render Usable website Service worker Network

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 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 86

Slide 86 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 87

Slide 87 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 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

@onishiweb

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

@onishiweb Tricky bits

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

@onishiweb chrome://serviceworker-internals/ @onishiweb

Slide 98

Slide 98 text

@onishiweb HTTPS only

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

@onishiweb How much can I cache?

Slide 101

Slide 101 text

@onishiweb Progressively enhancing the network

Slide 102

Slide 102 text

@onishiweb Browser support…

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

@onishiweb Return of the browser wars

Slide 105

Slide 105 text

@onishiweb Not really

Slide 106

Slide 106 text

@onishiweb Stop assuming

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

@onishiweb Be defensive

Slide 109

Slide 109 text

@onishiweb Improve performance

Slide 110

Slide 110 text

@onishiweb New shiny!

Slide 111

Slide 111 text

@onishiweb @onishiweb Thanks