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

Best viewed with... SOTB5

Adam Onishi
September 12, 2015

Best viewed with... SOTB5

My updated Best viewed with talk from State of the Browser 5

Adam Onishi

September 12, 2015
Tweet

More Decks by Adam Onishi

Other Decks in Technology

Transcript

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

    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 (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

    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
    Photo by Simon Collison - https://flic.kr/p/pbRdFm @onishiweb

    View Slide

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

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

    View Slide

  20. @onishiweb
    Control

    View Slide

  21. @onishiweb
    Defensive design

    View Slide

  22. @onishiweb
    What we do know

    View Slide

  23. @onishiweb
    Baseline

    View Slide

  24. @onishiweb
    Performance

    View Slide

  25. @onishiweb
    Perceived
    Performance

    View Slide

  26. @onishiweb

    View Slide

  27. @onishiweb

    View Slide

  28. @onishiweb
    Progressively
    enhanced
    performance

    View Slide

  29. @onishiweb
    Render blocking
    assets

    View Slide

  30. @onishiweb
    CSS, JS, & Fonts

    View Slide

  31. @onishiweb
    CSS

    View Slide

  32. @onishiweb
    CSS is still an
    enhancement

    View Slide

  33. @onishiweb
    CSS as an
    enhancement

    View Slide

  34. @onishiweb
    Critical Path CSS

    View Slide

  35. @onishiweb
    Tooling

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  39. @onishiweb
    Progressively
    enhancing CSS
    delivery

    View Slide

  40. @onishiweb
    Fonts

    View Slide

  41. @onishiweb
    We ❤ web fonts

    View Slide

  42. @onishiweb

    View Slide

  43. @onishiweb

    View Slide

  44. @onishiweb
    3s 3s
    3s ∞
    -

    View Slide

  45. @onishiweb
    Asynchronous font
    loading

    View Slide

  46. @onishiweb
    Font loading API

    View Slide

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

    View Slide

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

    View Slide

  49. @onishiweb
    Progressively
    enhancing font
    loading

    View Slide

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

    View Slide

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

    View Slide

  52. @onishiweb
    JavaScript

    View Slide

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

    View Slide

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

    View Slide

  55. @onishiweb

    View Slide

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

  57. @onishiweb
    Frameworks

    View Slide

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

    View Slide

  59. @onishiweb
    Is there a better
    way?

    View Slide

  60. @onishiweb
    Universal JavaScript

    View Slide

  61. @onishiweb
    Server Side
    rendering with
    Node.js

    View Slide

  62. @onishiweb
    React

    View Slide

  63. @onishiweb
    React.renderToString();

    View Slide

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

  65. @onishiweb
    Client side too

    View Slide

  66. @onishiweb
    GoCardless

    View Slide

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

  68. @onishiweb
    Progressively
    enhancing
    JavaScript
    frameworks

    View Slide

  69. @onishiweb
    Control

    View Slide

  70. @onishiweb
    The Network

    View Slide

  71. @onishiweb
    Assumption

    View Slide

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

    View Slide

  73. @onishiweb
    Mobile connectivity

    View Slide

  74. @onishiweb
    Cake or Death?

    View Slide

  75. @onishiweb
    Enter Service
    Worker

    View Slide

  76. @onishiweb
    Web vs Native!

    View Slide

  77. @onishiweb
    The web is going
    offline!

    View Slide

  78. @onishiweb
    Browser cache

    View Slide

  79. @onishiweb
    @onishiweb

    View Slide

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

    View Slide

  81. @onishiweb
    Cache
    Request
    Render
    Usable
    website
    Service worker
    Network

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

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

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

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  92. @onishiweb

    View Slide

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

    View Slide

  94. @onishiweb
    Tricky bits

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  98. @onishiweb
    HTTPS only

    View Slide

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

    View Slide

  100. @onishiweb
    How much can I
    cache?

    View Slide

  101. @onishiweb
    Progressively
    enhancing the
    network

    View Slide

  102. @onishiweb
    Browser support…

    View Slide

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

    View Slide

  104. @onishiweb
    Return of the
    browser wars

    View Slide

  105. @onishiweb
    Not really

    View Slide

  106. @onishiweb
    Stop assuming

    View Slide

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

    View Slide

  108. @onishiweb
    Be defensive

    View Slide

  109. @onishiweb
    Improve
    performance

    View Slide

  110. @onishiweb
    New shiny!

    View Slide

  111. @onishiweb
    @onishiweb
    Thanks

    View Slide