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!

F085bf2092cb300bac787cc5bc65d301?s=128

Ryan Townsend

October 31, 2018
Tweet

Transcript

  1. Leeds JS 2018 Building fast websites against all odds Photo

    by Emil Vilsek on Unsplash Slides – twnsnd.com/leedsjs2018
  2. Who am I? Ryan Townsend CTO, SHIFT – @ryantownsend

  3. None
  4. Performance is pretty important… ‘Why Fast Matters’ by @csswizardry –

    https://bit.ly/2kiVDAz
  5. Traffic x Conversion Rate x AOV =

  6. Performance = Traffic

  7. “The result of rebuilding our pages for performance led to

    [...] a 15 percent increase in SEO traffic” – Pinterest Source – https://bit.ly/2ICPv4Z
  8. “[…] starting in July 2018, page speed will be a

    ranking factor for mobile searches.” – Google #SpeedUpdate Source – https://bit.ly/2Dt5Plz
  9. Performance = Conversion

  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
  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
  12. Performance = AOV

  13. +9.6% pages/session

  14. +8.7% AOV

  15. Performance x Performance x Performance =

  16. But it’s not that easy…

  17. Selling performance can be tricky

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

  20. Smithsonian Institution Neg. 83-14878. “It's easier to ask forgiveness than

    it is to get permission.” – Grace Hopper
  21. Before we start optimising…

  22. Monitor & Measure

  23. SpeedCurve https:/ /speedcurve.com/

  24. Understand your users and build for the future

  25. None
  26. The Slowest Site in the World

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

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

  30. Initial Results? • Start render: 6.4s • SpeedIndex: 12717 •

    Interactive: 4.4s • Bandwidth: 2,594 KB
  31. None
  32. Guide – https://is.gd/DsjOur

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

    6. Images
  34. Connection

  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
  36. HTML

  37. <head>

  38. Correct Order 1. <meta> character encoding / viewport 2. <title>

    3. Resource hints 4. Inline <script> 5. External stylesheet 6. Inline <style> 7. External <script> 8. Anything else, e.g. other meta tags “Get Your <head> Straight” – @csswizardry
  39. Resource Hints • DNS Prefetch • Preconnect (CDN, 3rd parties)

    • Preload (CSS @imports, @font-face etc) • Prefetch (low priority preload)
  40. None
  41. Progressive-enhancement, 80% support

  42. Use as fallback for preconnect in IE & Edge

  43. Progressive-enhancement, 77% support

  44. Results?

  45. Start Render SpeedIndex Interactive Bandwidth (-1.8s) (+184) (-0.1s) (no change)

    Value: $6,782,202 / year Value based on Mobify case study
  46. CSS

  47. Remove @import

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

  49. Inline (Critical) CSS

  50. None
  51. Load below-the-fold CSS asynchronously

  52. Results?

  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)
  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)
  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)
  56. Webfonts

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

  58. font-display: optional / swap

  59. Progressive-enhancement, 77% support

  60. WOFF2 (30% average size reduction)

  61. 88% support, serve WOFF1 for Internet Explorer

  62. unicode-range (bundling for web fonts)

  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; }
  64. Results?

  65. Start Render SpeedIndex Interactive Bandwidth (-1.8s) (-258) (-0.1s) (no change)

    Value: $6,782,202 / year Value based on Mobify case study
  66. JavaScript

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

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

  69. “Use a CDN”, they said

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

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

  72. Bundling & Tree-shaking

  73. Results?

  74. Start Render SpeedIndex Interactive Bandwidth (-0.1s) (-691) (-2.2s) (-5KB) Value:

    $376,789 / year Value based on Mobify case study
  75. Images

  76. Foreground vs Background

  77. <img src=“image.jpg” /> background-image: url(image.jpg) vs

  78. Hero loaded after lower-priority product images

  79. Corrected by using a foreground <img>

  80. Serve Appropriate Sizes

  81. Progressive enhancement, 89% support

  82. Serve Appropriate Formats

  83. 38%, Safari only

  84. 6%, IE/Edge only

  85. 47%, Blink only

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

  87. <picture> <!--[if IE 9]><video style="display: none;><![endif]--> <source srcset='hero@1600w.jxr 1600w, ...'

    type='image/vnd.ms-photo' /> <source srcset='hero@1600w.jp2 1600w, ...' type='image/jp2' /> <source srcset='hero@1600w.webp 1600w, ...' type='image/webp' /> <!--[if IE 9]></video><![endif]--> <img srcset=' hero@1600w.jpg 1600w, hero@1400w.jpg 1400w, hero@1200w.jpg 1200w, ...' src='hero@400w.jpg' alt='Hero Image' /> </picture> our different formats our different sizes fallback to JPEG with an old-school <img> ‘src’
  88. Lazy-load Beneath the Fold

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

  91. Results?

  92. Start Render SpeedIndex Interactive Bandwidth (-1.7s) (-6948) (-0.1s) (-2,224KB) Value:

    $6,405,413 / year Value based on Mobify case study
  93. https://images.guide/

  94. Show me the money…

  95. Start Render SpeedIndex Interactive Bandwidth (-3.8s) (-8486) (-2.1s) (-2,229KB) Value:

    $14,317,982 / year Value based on Mobify case study
  96. Original Optimised https://bit.ly/2IViWzf

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

  98. Bonus Point!

  99. Service Workers

  100. Progressive-enhancement, 80% support

  101. • Progressive enhancement • Network control • Offline support •

    Progressive Web Apps (PWAs) • stale-while-revalidate / stale-while-error • Protect against 3rd party slow-downs
  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
  103. Thank you! Ryan Townsend CTO, SHIFT – @ryantownsend twnsnd.com/leedsjs2018

  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
  105. It’s gonna get expensive

  106. “But the carousel!”

  107. None
  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
  109. Why don’t we just build fast sites in the first

    place?