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

Building Fast Websites Against All Odds - Leeds JS 2018

Building Fast Websites Against All Odds - Leeds JS 2018

Event: https://www.meetup.com/LeedsJS/events/255547488/

Fast website performance is essential for a great user experience, particularly in rural areas or emerging markets where poor connectivity and low-power devices can struggle with even the most optimised sites, yet it can still seem impossible to convince clients and stakeholders of the value that performance holds.

Now, I can’t promise that I can magically transform your clients’ attitudes toward performance, but what I can do show is show you how to build a fast website without even involving them. In my work delivering high-performance, high-availability websites for some of the UK’s biggest retailers, I’ve come up with a wealth of ways in which we as front-end developers can improve performance without the need for any costly rewrites, new infrastructure, or any kind of work that requires permission (and budget!).

We may not be able to make the _fastest_ website without permission, but we can certainly make a fast one!

Ryan Townsend

October 31, 2018
Tweet

More Decks by Ryan Townsend

Other Decks in Programming

Transcript

  1. Leeds JS 2018
    Building fast websites
    against all odds
    Photo by Emil Vilsek on Unsplash
    Slides – twnsnd.com/leedsjs2018

    View Slide

  2. Who am I?
    Ryan Townsend
    CTO, SHIFT – @ryantownsend

    View Slide

  3. View Slide

  4. Performance is pretty important…
    ‘Why Fast Matters’ by @csswizardry – https://bit.ly/2kiVDAz

    View Slide

  5. Traffic x Conversion Rate x AOV
    =

    View Slide

  6. Performance = Traffic

    View Slide

  7. “The result of rebuilding our pages for
    performance led to [...] a 15 percent
    increase in SEO traffic”
    – Pinterest
    Source – https://bit.ly/2ICPv4Z

    View Slide

  8. “[…] starting in July 2018, page speed will
    be a ranking factor for mobile searches.”
    – Google #SpeedUpdate
    Source – https://bit.ly/2Dt5Plz

    View Slide

  9. Performance = Conversion

    View Slide

  10. “For every 100ms decrease in homepage load
    speed, Mobify's customer base saw a 1.11% lift in
    session based conversion, amounting to an
    average annual revenue increase of $376,789”
    – Mobify
    Source – https://bit.ly/2s0FDHS

    View Slide

  11. “Similarly, for every 100ms decrease in checkout
    page load speed, Mobify's customers saw a 1.55%
    lift in session based conversion, amounting to an
    average annual revenue increase of $526,147”
    – Mobify
    Source – https://bit.ly/2s0FDHS

    View Slide

  12. Performance = AOV

    View Slide

  13. +9.6% pages/session

    View Slide

  14. +8.7% AOV

    View Slide

  15. Performance x Performance x
    Performance =

    View Slide

  16. But it’s not that easy…

    View Slide

  17. Selling performance
    can be tricky

    View Slide

  18. View Slide

  19. You don’t need permission
    to build fast websites

    View Slide

  20. Smithsonian Institution Neg. 83-14878.
    “It's easier to ask forgiveness
    than it is to get permission.”
    – Grace Hopper

    View Slide

  21. Before we start optimising…

    View Slide

  22. Monitor & Measure

    View Slide

  23. SpeedCurve
    https:/
    /speedcurve.com/

    View Slide

  24. Understand your users and
    build for the future

    View Slide

  25. View Slide

  26. The Slowest Site in the World

    View Slide

  27. github.com/ryantownsend/slowest-site-in-the-world

    View Slide

  28. View Slide

  29. https:/
    /www.webpagetest.org/easy

    View Slide

  30. Initial Results?
    • Start render: 6.4s
    • SpeedIndex: 12717
    • Interactive: 4.4s
    • Bandwidth: 2,594 KB

    View Slide

  31. View Slide

  32. Guide – https://is.gd/DsjOur

    View Slide

  33. 1. Connection
    2. HTML
    3. CSS
    4. Webfonts
    5. JavaScript
    6. Images

    View Slide

  34. Connection

    View Slide

  35. You can’t control your infrastructure without
    permission, but you can check features are enabled:
    • GZIP / Brotli
    • OCSP for SSL
    • HTTP/2
    • Connection: keep-alive

    View Slide

  36. HTML

    View Slide


  37. View Slide

  38. Correct Order
    1. character encoding / viewport
    2.
    3. Resource hints
    4. Inline <br/>5. External stylesheet<br/>6. Inline <style><br/>7. External <script><br/>8. Anything else, e.g. other meta tags<br/>“Get Your <head> Straight” – @csswizardry<br/>

    View Slide

  39. Resource Hints
    • DNS Prefetch
    • Preconnect (CDN, 3rd parties)
    • Preload (CSS @imports, @font-face etc)
    • Prefetch (low priority preload)

    View Slide

  40. View Slide

  41. Progressive-enhancement, 80% support

    View Slide

  42. Use as fallback for preconnect in IE & Edge

    View Slide

  43. Progressive-enhancement, 77% support

    View Slide

  44. Results?

    View Slide

  45. Start Render SpeedIndex Interactive Bandwidth
    (-1.8s) (+184) (-0.1s) (no change)
    Value: $6,782,202 / year
    Value based on Mobify case study

    View Slide

  46. CSS

    View Slide

  47. Remove @import

    View Slide

  48. Don’t let third parties control your
    performance, uptime or security

    View Slide

  49. Inline (Critical) CSS

    View Slide

  50. View Slide

  51. Load below-the-fold CSS
    asynchronously

    View Slide

  52. Results?

    View Slide

  53. Start Render SpeedIndex Interactive Bandwidth
    (-0.1s) (-348) (-0.2s) (no change)
    Value: $376,789 / year
    Value based on Mobify case study
    (ideal conditions)

    View Slide

  54. Start Render SpeedIndex Interactive Bandwidth
    (-90.1s) (-∞) (-0.2s) (no change)
    Value: $339,486,889 / year
    Value based on Mobify case study
    (3rd party offline)

    View Slide

  55. Start Render SpeedIndex Interactive Bandwidth
    (-90.1s) (-∞) (-0.2s) (no change)
    Value: $38,754 / hour
    Value based on Mobify case study
    (3rd party offline)

    View Slide

  56. Webfonts

    View Slide

  57. Self-host
    https://google-webfonts-helper.herokuapp.com/fonts

    View Slide

  58. font-display: optional / swap

    View Slide

  59. Progressive-enhancement, 77% support

    View Slide

  60. WOFF2
    (30% average size reduction)

    View Slide

  61. 88% support, serve WOFF1 for Internet Explorer

    View Slide

  62. unicode-range
    (bundling for web fonts)

    View Slide

  63. /* latin */
    @font-face {
    font-family: 'Montserrat';
    font-style: normal;
    font-weight: 400;
    src: local('Montserrat Regular'), local(‘Montserrat-Regular'),
    url(/fonts/montserrat.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
    U+02C6,
    U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
    font-display: swap;
    }

    View Slide

  64. Results?

    View Slide

  65. Start Render SpeedIndex Interactive Bandwidth
    (-1.8s) (-258) (-0.1s) (no change)
    Value: $6,782,202 / year
    Value based on Mobify case study

    View Slide

  66. JavaScript

    View Slide

  67. Sync vs Async vs Defer
    still valuable!
    to be avoided!

    View Slide

  68. Source – https://is.gd/w4tCW9

    View Slide

  69. “Use a CDN”, they said

    View Slide

  70. https://cdnjs.cloudflare.com/ajax/
    libs/jquery/3.3.1/jquery.min.js
    (to be avoided!)

    View Slide

  71. Source – https://bit.ly/2ij5XIt

    View Slide

  72. Bundling & Tree-shaking

    View Slide

  73. Results?

    View Slide

  74. Start Render SpeedIndex Interactive Bandwidth
    (-0.1s) (-691) (-2.2s) (-5KB)
    Value: $376,789 / year
    Value based on Mobify case study

    View Slide

  75. Images

    View Slide

  76. Foreground vs Background

    View Slide


  77. background-image: url(image.jpg)
    vs

    View Slide

  78. Hero loaded after lower-priority product images

    View Slide

  79. Corrected by using a foreground

    View Slide

  80. Serve Appropriate Sizes

    View Slide

  81. Progressive enhancement, 89% support

    View Slide

  82. Serve Appropriate Formats

    View Slide

  83. 38%, Safari only

    View Slide

  84. 6%, IE/Edge only

    View Slide

  85. 47%, Blink only

    View Slide

  86. Accept: image/webp,image/*,*/*;q=0.8

    View Slide







  87. src='[email protected]'
    alt='Hero Image'
    />

    our different formats
    our different sizes
    fallback to JPEG with an old-school ‘src’

    View Slide

  88. Lazy-load Beneath the Fold

    View Slide

  89. View Slide

  90. Source – medium.com
    Low-Quality Image Preview (LQIP)

    View Slide

  91. Results?

    View Slide

  92. Start Render SpeedIndex Interactive Bandwidth
    (-1.7s) (-6948) (-0.1s) (-2,224KB)
    Value: $6,405,413 / year
    Value based on Mobify case study

    View Slide

  93. https://images.guide/

    View Slide

  94. Show me the money…

    View Slide

  95. Start Render SpeedIndex Interactive Bandwidth
    (-3.8s) (-8486) (-2.1s) (-2,229KB)
    Value: $14,317,982 / year
    Value based on Mobify case study

    View Slide

  96. Original Optimised
    https://bit.ly/2IViWzf

    View Slide

  97. Low-hanging fruit can have
    immense impact on performance

    View Slide

  98. Bonus Point!

    View Slide

  99. Service Workers

    View Slide

  100. Progressive-enhancement, 80% support

    View Slide

  101. • Progressive enhancement
    • Network control
    • Offline support
    • Progressive Web Apps (PWAs)
    • stale-while-revalidate / stale-while-error
    • Protect against 3rd party slow-downs

    View Slide

  102. function timeout(delay){
    return new Promise(function(resolve, reject) {
    setTimeout(function() {
    resolve(new Response('', {
    status: 408,
    statusText: 'Request timed out.'
    }))
    }, delay)
    })
    }
    self.addEventListener('fetch', function(event) {
    // @paulirish fix for DevTools
    if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') {
    return
    // if the request is not for example.com, serve requests normally
    } else if (!event.request.url.includes('example.com')) {
    return
    }
    return event.respondWith(caches.match(event.request).then(function(response) {
    return response || Promise.race([
    timeout(2000),
    fetch(event.request)
    ])
    }))
    })
    attempt the request
    force a 2-second timeout

    View Slide

  103. Thank you!
    Ryan Townsend
    CTO, SHIFT – @ryantownsend
    twnsnd.com/leedsjs2018

    View Slide

  104. • Replica of your site
    • Restricted HTML: limited AMP elements
    • Restricted JS: no custom JS allowed
    • Restricted CSS: inlined, 50kb max
    • No repaint: fixed element sizing
    • No desktop: mobile-only
    • Shown within Google’s branding
    • Stale-while-revalidate: minimum 15 seconds refresh
    • Extra QA effort

    View Slide

  105. It’s gonna get expensive

    View Slide

  106. “But the carousel!”

    View Slide

  107. View Slide

  108. “[…] we now feel ready to take the next step and
    work to support more instant-loading content not
    based on AMP technology in areas of Google Search
    designed for this, like the Top Stories carousel”
    – AMP Project @ Google
    Source – https://bit.ly/2JakbtC

    View Slide

  109. Why don’t we just build fast
    sites in the first place?

    View Slide