Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Best viewed with - Velocity Amsterdam 2015

Adam Onishi
October 30, 2015

Best viewed with - Velocity Amsterdam 2015

Are we doomed to see history repeat itself? With the amount of client-side MVC frameworks and the upcoming implementation of the ES6 syntax, will we soon be seeing a repeat of the “browser wars.” Will more websites only work in a select number of browsers with the capabilities to run their code?

Are we breaking the inherent robustness of the web? The main facets that affect everything on the web are performance, accessibility, interaction. What are these new tools serving most?

My aim is to take a look at the current state of the web and whether progressive enhancement is still plausible, instead of looking at what new tools can offer. Do some of these new frameworks start to redress the balance and serve all facets of the web?

I’ll be covering:

- What progressive enhancement is and whether it is still important
- What new JavaScript frameworks are offering
- The broader picture of progressive enhancement and what that means for performance and accessibility
- An introduction to service worker and what that means to progressive enhancement and performance

Adam Onishi

October 30, 2015
Tweet

More Decks by Adam Onishi

Other Decks in Technology

Transcript

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

    View Slide

  2. @onishiweb
    A long time ago…

    View Slide

  3. @onishiweb
    @onishiweb

    View Slide

  4. @onishiweb

    View Slide

  5. @onishiweb
    “Browser wars!”

    View Slide

  6. @onishiweb
    @onishiweb

    View Slide

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

    View Slide

  8. @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

    View Slide

  9. @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

    View Slide

  10. @onishiweb

    View Slide

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

    View Slide

  12. @onishiweb
    Developer-first
    development

    View Slide

  13. @onishiweb
    Cake or Death?

    View Slide

  14. @onishiweb
    Progressive
    enhancement

    View Slide

  15. @onishiweb
    “Vague, but exciting”

    View Slide

  16. @onishiweb
    The
    Web
    JS
    CSS
    HTML
    Internet

    View Slide

  17. @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

    View Slide

  18. @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

    View Slide

  19. @onishiweb
    Photo from EdgeConf 2015 @onishiweb

    View Slide

  20. @onishiweb

    View Slide

  21. @onishiweb
    Control

    View Slide

  22. @onishiweb
    Defensive design

    View Slide

  23. @onishiweb
    What we do know

    View Slide

  24. @onishiweb
    Baseline

    View Slide

  25. @onishiweb
    Performance

    View Slide

  26. @onishiweb
    Performance
    Perceived

    View Slide

  27. @onishiweb

    View Slide

  28. @onishiweb

    View Slide

  29. @onishiweb
    Progressively enhanced
    performance

    View Slide

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

    View Slide

  31. @onishiweb
    Render blocking assets

    View Slide

  32. @onishiweb
    CSS, Fonts, and JavaScript

    View Slide

  33. @onishiweb
    Browser rendering

    View Slide

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

    View Slide

  35. @onishiweb
    Stuff
    Request Render
    Stuff
    Stuff
    Stuff
    Stuff
    Stuff
    Stuff

    View Slide

  36. @onishiweb
    CSS

    View Slide

  37. @onishiweb
    CSS is still an enhancement

    View Slide

  38. @onishiweb
    CSS as an enhancement

    View Slide

  39. @onishiweb
    Critical Path CSS

    View Slide

  40. @onishiweb
    Tooling

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  44. @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);
    });
    });

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  48. @onishiweb
    onload="this.rel='stylesheet'">
    <br/>function loadCSS(e,t,n) { ... }<br/>function preloadSupported() { ... }<br/>if( ! preloadSupported() ){<br/>loadCSS( asyncCSS.href );<br/>}<br/>

    View Slide

  49. @onishiweb
    Cache locally

    View Slide

  50. @onishiweb
    Progressively enhancing
    CSS delivery

    View Slide

  51. @onishiweb
    Fonts

    View Slide

  52. @onishiweb
    We ❤ web fonts

    View Slide

  53. @onishiweb

    View Slide

  54. @onishiweb

    View Slide

  55. @onishiweb
    3s 3s
    3s ∞
    -

    View Slide

  56. @onishiweb
    Asynchronous font loading

    View Slide

  57. @onishiweb
    Font loading API

    View Slide

  58. @onishiweb
    FOUT
    FOIT

    View Slide

  59. @onishiweb
    Flash Of Unstyled Text
    Flash Of Invisible Text

    View Slide

  60. @onishiweb
    FOUT vs FOIT

    View Slide

  61. @onishiweb
    Control over fonts

    View Slide

  62. @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";
    });

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  68. @onishiweb
    Font display
    ❌ ❌
    ❌ ❌

    View Slide

  69. @onishiweb
    Progressively enhancing
    font loading

    View Slide

  70. @onishiweb
    JavaScript

    View Slide

  71. @onishiweb
    @onishiweb

    View Slide

  72. @onishiweb
    @onishiweb

    View Slide

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

    View Slide

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

    View Slide

  75. @onishiweb

    View Slide

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

    View Slide

  77. @onishiweb
    Frameworks

    View Slide

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

    View Slide

  79. @onishiweb
    Is there a better way?

    View Slide

  80. @onishiweb
    Universal JavaScript

    View Slide

  81. @onishiweb
    Server Side rendering with
    Node.js

    View Slide

  82. @onishiweb
    React

    View Slide

  83. @onishiweb
    React.renderToString();

    View Slide

  84. @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 });
    });

    View Slide

  85. @onishiweb
    Client side too

    View Slide

  86. @onishiweb
    GoCardless

    View Slide

  87. @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.”

    View Slide

  88. @onishiweb
    Progressively enhancing
    JavaScript frameworks

    View Slide

  89. @onishiweb
    Control

    View Slide

  90. @onishiweb
    @onishiweb

    View Slide

  91. @onishiweb
    Render blocking assets

    View Slide

  92. @onishiweb
    Stuff
    Request Render
    Stuff
    Stuff
    Stuff
    Stuff
    Stuff
    Stuff

    View Slide

  93. @onishiweb
    Stuff
    Request Render

    View Slide

  94. @onishiweb
    The Network

    View Slide

  95. @onishiweb
    The
    Web
    JS
    CSS
    HTML
    Internet

    View Slide

  96. @onishiweb
    Stuff
    Request Render
    Network

    View Slide

  97. @onishiweb
    Assumption

    View Slide

  98. @onishiweb
    @onishiweb

    View Slide

  99. @onishiweb
    Mobile connectivity

    View Slide

  100. @onishiweb
    Cake or Death?

    View Slide

  101. @onishiweb
    Enter ServiceWorker

    View Slide

  102. @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

    View Slide

  103. @onishiweb
    Web vs Native!

    View Slide

  104. @onishiweb
    The web is going offline!

    View Slide

  105. @onishiweb
    Browser cache

    View Slide

  106. @onishiweb
    @onishiweb

    View Slide

  107. @onishiweb
    Cache
    content
    Register
    SW
    Stuff
    Request Render

    View Slide

  108. @onishiweb
    Cache
    Stuff
    Request Render
    SW

    View Slide

  109. @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);
    });
    }

    View Slide

  110. @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'
    ]);
    })
    )
    });

    View Slide

  111. @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);
    }
    )
    );
    });

    View Slide

  112. @onishiweb

    View Slide

  113. @onishiweb
    Cache, falling
    back to network

    View Slide

  114. @onishiweb
    Stale content

    View Slide

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

    View Slide

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

    View Slide

  117. @onishiweb
    Twitter screenshot

    View Slide

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

    View Slide

  119. @onishiweb
    Diving in head first…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  124. @onishiweb
    HTTPS only

    View Slide

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

    View Slide

  126. @onishiweb
    How much can I cache?

    View Slide

  127. @onishiweb
    Browser support…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  132. @onishiweb
    Progressively enhancing the
    network

    View Slide

  133. @onishiweb
    Return of the
    “browser wars”

    View Slide

  134. @onishiweb
    Not really

    View Slide

  135. @onishiweb
    Stop assuming

    View Slide

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

    View Slide

  137. @onishiweb
    Be defensive

    View Slide

  138. @onishiweb
    Improve performance

    View Slide

  139. @onishiweb
    Critical Path CSS

    View Slide

  140. @onishiweb
    Critical Path CSS
    Font Loading API

    View Slide

  141. @onishiweb
    Critical Path CSS
    Font Loading API
    Universal JavaScript

    View Slide

  142. @onishiweb
    Critical Path CSS
    Font Loading API
    Universal JavaScript
    ServiceWorker

    View Slide

  143. @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”

    View Slide

  144. @onishiweb
    Thanks
    Adam Onishi
    Velocity Conf Amsterdam - October 2015

    View Slide

  145. @onishiweb
    Questions?

    View Slide