Help! My client is a WebPerf meetup!

Fc7368fd45560e1e7401bc80684f5867?s=47 Adam Onishi
November 07, 2016

Help! My client is a WebPerf meetup!

At first it seems like a good idea. The chance to build the website for one of your favourite meetups. Great! Then the realisation dawns on you. They’re not just a great meetup, they’re a WebPerf meetup, hosting some of the most performance-minded developers in our industry.

Challenge accepted!

Follow along as I take you on a journey through the project from design to deployment. We’ll look at all the steps taken to ensure the site could pass the tough scrutiny of the WebPerf community. We’ll cover design considerations, font choices, the tools for optimising front-end assets, and performance testing.

Finally, we’ll go one step further and see how service workers can be used to improve site performance with client-side caching techniques.

Fc7368fd45560e1e7401bc80684f5867?s=128

Adam Onishi

November 07, 2016
Tweet

Transcript

  1. Adam Onishi LDN WebPerf @onishiweb Help! My client is a

    #WebPerf meetup!
  2. None
  3. Velocity Conf Amsterdam 2015

  4. None
  5. @onishiweb

  6. @onishiweb

  7. @onishiweb

  8. Building a website for the WebPerf community

  9. 1. Testing & Metrics 2. Design 3. Images 4. Styles

    & Scripts 5. Fonts 6. Hosting & CDN
  10. 7. Images (pt. 2) 8. Fonts (pt. 2) 9. Service

    Worker 10. Styles (pt. 2) 11. Conclusion
  11. Testing & Metrics

  12. Speed Index

  13. ” “How much of the above- the-fold content is visually

    complete over time until it is 100% complete Daniel Imms
  14. Start Render

  15. @onishiweb

  16. https:/ /www.webpagetest.org/

  17. PageSpeed Insights

  18. Yellow Lab Tools

  19. Cost

  20. https:/ /whatdoesmysitecost.com/

  21. 3G in London Testing the homepage First visit only @onishiweb

  22. ” “…since the browser can ditch the cache whenever it

    wants, it shouldn't be relied upon Jake Archibald
  23. @onishiweb

  24. Benchmarks

  25. http:/ /www.meetup.com/London-Web-Performance-Group/

  26. 4983 4.783s 33/100 $$$$$ http:/ /www.meetup.com/London-Web-Performance-Group/

  27. http:/ /www.frontendlondon.co.uk/

  28. 1658 1.387s 92/100 $ http:/ /www.frontendlondon.co.uk/

  29. One more… @onishiweb

  30. None
  31. Client happiness

  32. Design

  33. Performance starts at design

  34. ” “The decisions made by designers are what typically drive

    the rest of how a website is built Lara Hogan
  35. Specifics… @onishiweb

  36. Banner images

  37. @onishiweb

  38. http:/ /www.webdesign-inspiration.com/web-designs/page/2

  39. High-res banner images! @onishiweb

  40. What if… @onishiweb

  41. https:/ /ldnwebperf.org/about-us/

  42. CSS Blend Modes @onishiweb

  43. Reduce image quality without losing the effect @onishiweb

  44. Fonts

  45. @onishiweb

  46. Limit weights and styles @onishiweb

  47. Custom font for headings, system font for body @onishiweb

  48. Designers should know how the web works.

  49. @onishiweb Good designers make this stuff easy @onishiweb

  50. None
  51. Images

  52. Content images @onishiweb

  53. https:/ /ldnwebperf.org/

  54. The responsive web https:/ /ldnwebperf.org/

  55. What about when there’s a new sponsor? @onishiweb

  56. You can’t expect the client to do all the optimising

    @onishiweb
  57. Even if they are a #WebPerf expert! @onishiweb

  58. https:/ /en-gb.wordpress.org/plugins/wp-smushit/

  59. https:/ /wordpress.org/plugins/winsite-image-optimizer/

  60. You can’t expect the client to do all the optimising

    @onishiweb
  61. None
  62. Dimensions: 2044 × 1150 @onishiweb

  63. Before: 2044 × 1150 (103Kb) After: 400 × 212 (11Kb)

    @onishiweb
  64. add_image_size( 'speaker-thumb', 55, 55, true ); add_image_size( 'event-image', 400, 212,

    true );
  65. 2552 Optimisation: Image compression

  66. 2.296s Optimisation: Image compression

  67. $ Optimisation: Image compression

  68. Optimisation: Image compression

  69. Styles & Scripts

  70. Build steps… @onishiweb

  71. Critical path CSS @onishiweb

  72. ” “It goes against everything we’ve been taught as front-end

    developers Patrick Hamann
  73. ” “…if done correctly can be used to deliver a

    “one roundtrip” critical path length where only the HTML is a blocking resource. Addy Osmani
  74. @onishiweb • Critical • Penthouse • LoadCSS

  75. ” “Ideally, the [above the fold] content should fit under

    14KB PageSpeed Insights
  76. Stylestats @onishiweb

  77. ├─────────────────────────────┼─────────────────┤ │ Style Sheets │ 1 ├─────────────────────────────┼─────────────────┤ │ Size │

    28.6KB ├─────────────────────────────┼─────────────────┤ │ Gzipped Size │ 5.7KB ├─────────────────────────────┼─────────────────┤
  78. function lwp_inline_styles() { if (file_exists( get_template_directory() . '/css/ main.min.css')) {

    $css = file_get_contents(get_template_directory_uri() . '/ css/main.min.css'); if (false !== $css) { echo '<style>' . $css . '</style>'; return; } } echo '<link rel="stylesheet" href="' . get_stylesheet_directory_uri() . '/css/main.min.css" type="text/css" media="all" />'; } add_action( 'wp_head', 'lwp_inline_styles', 50);
  79. Async scripts @onishiweb

  80. function lwp_async_defer_script($tag, $handle) { $src_async = ' async="async" defer="defer" src';

    if ('webperf-scripts' === $handle) { return str_replace(' src', $src_async, $tag ); } return $tag; } add_action('script_loader_tag', 'lwp_async_defer_script');
  81. 2552 -4 2548 Optimisation: Styles and Scripts

  82. 2.296s +0.192s 2.488s Optimisation: Styles and Scripts

  83. Fonts

  84. Google Fonts @onishiweb

  85. https:/ /fonts.google.com/specimen/Work+Sans?selection.family=Work+Sans

  86. <link href="https://fonts.googleapis.com/ css?family=Work+Sans" rel="stylesheet">

  87. Self-hosting Google Fonts @onishiweb

  88. https:/ /google-webfonts-helper.herokuapp.com/fonts/

  89. 2548 -511 2037 Optimisation: Fonts

  90. 2.488s -0.896 1.592s Optimisation: Fonts

  91. 84/100 Optimisation: Fonts

  92. Optimisation: Fonts

  93. Hosting & CDN

  94. @onishiweb

  95. This could all change with PHP7 @onishiweb

  96. http:/ /talks.php.net/china16#/

  97. http:/ /talks.php.net/china16#/

  98. https:/ /wpengine.com/

  99. ” “At WP Engine, there’s no confusing caching plugins WPEngine

    blog
  100. Nothing enabled on staging @onishiweb

  101. @onishiweb

  102. ” “Quick WPT reveals a bit of image optimisation and

    CDN use as the main issues on home page. Perry Dyball
  103. @onishiweb

  104. @onishiweb

  105. ” “Akamai are setting up a CDN account for us.

    Perry Dyball
  106. 2037 -1125 912 Optimisation: Hosting & CDN

  107. 1.592s -0.701 0.891s Optimisation: Hosting & CDN

  108. Optimisation: Hosting & CDN 84/100 +15 99/100

  109. @onishiweb

  110. London, UK Chrome - ? @onishiweb

  111. London, UK Chrome - Cable @onishiweb

  112. @onishiweb

  113. 2037 +15 2052 Optimisation: Hosting & CDN

  114. 1.592s +0.097 1.689s Optimisation: Hosting & CDN

  115. 99/100 Optimisation: Hosting & CDN 84/100 +15

  116. 97/100 Optimisation: Hosting & CDN

  117. Optimisation: Hosting & CDN

  118. Images (pt. 2)

  119. http:/ /yellowlab.tools/result/ej2ql2k0qi

  120. Lazy loading below the fold images @onishiweb

  121. https:/ /github.com/toddmotto/echo

  122. function lwp_image_atts($attr) { if($attr['srcset']) { return $attr; } if($attr['src']) {

    $attr['data-echo'] = $attr['src']; $attr['src'] = get_template_directory_uri() . '/ img/blanc.gif'; $attr['class'].= ' img--loading'; } return $attr; } add_filter('wp_get_attachment_image_attributes', 'lwp_image_atts');
  123. if(document.querySelectorAll('img').length) { // Init the echo JS loader echo.init({ callback:

    function(element, op) { element.classList.remove('img--loading'); } }); }
  124. http:/ /ldnwebperf.org/

  125. SVGs @onishiweb

  126. https:/ /speakerdeck.com/ninjanails/death-to-icon-fonts-2

  127. Colouring SVGs @onishiweb

  128. function inlineSvg() { var ajax = new XMLHttpRequest(); ajax.open("GET", "/icons.svg",

    true); ajax.send(); ajax.onload = function(e) { var div = document.createElement("div"); div.style.display = 'none'; div.innerHTML = ajax.responseText; document.body.appendChild(div); }; }
  129. 2052 -290 1762 Optimisation: Images (pt. 2)

  130. 1.689s -0.306 1.383s Optimisation: Images (pt. 2)

  131. 98/100 Optimisation: Images (pt. 2) 97/100 +1

  132. Fonts (pt. 2)

  133. https:/ /www.zachleat.com/web/comprehensive-webfonts/

  134. Critical FOFT (Flash of Fallback Text) @onishiweb

  135. @onishiweb

  136. Web Font Loader @onishiweb

  137. .wf-loading .wf-active .wf-inactive .wf-<familyname>-<fvd>-loading .wf-<familyname>-<fvd>-active .wf-<familyname>-<fvd>-inactive @onishiweb

  138. .wf-loading body { font-family: $font-fallback; }

  139. 1762 -329 1433 Optimisation: Fonts (pt. 2)

  140. Service Worker

  141. So far… @onishiweb

  142. First view only @onishiweb

  143. Navigating through the site @onishiweb

  144. https:/ /remysharp.com/2016/03/22/the-copy--paste-guide-to-your-first-service-worker

  145. Stale-while-revalidate @onishiweb

  146. What about a Progressive Web App? @onishiweb

  147. @onishiweb 1. HTTPS 2. Service Worker 3. Manifest

  148. Optimisation: Service Worker 91/100

  149. Not a “PWA” @onishiweb

  150. ” “…the manifest display property must be set to 'standalone'

    or 'fullscreen' Chrome
  151. ? ? ? Optimisation: Service Worker

  152. Styles (pt. 2)

  153. Tooling

  154. http:/ /yellowlab.tools/result/ej2ql2k0qi

  155. Autoprefixer @onishiweb

  156. npm update --save

  157. "gulp-autoprefixer": "^3.1.1"

  158. Inline styles (again)

  159. ” “Ideally, the [above the fold] content should fit under

    14KB PageSpeed Insights
  160. Dumping all styles inline, probably not a great idea @onishiweb

  161. Generating “head.css” @onishiweb

  162. @onishiweb • Critical • Penthouse • LoadCSS

  163. Custom inline CSS @onishiweb

  164. None
  165. LoadCSS @onishiweb

  166. https:/ /github.com/filamentgroup/loadCSS/#recommended-usage-pattern

  167. 1433 -54 1379 Optimisation: Styles (pt. 2)

  168. 1.383s -0.096 1.287s Optimisation: Styles (pt. 2)

  169. 99/100 Optimisation: Styles (pt. 2) 98/100 +1

  170. Conclusion

  171. Performance starts with design @onishiweb

  172. Do the work so your content editors don’t have to

    @onishiweb
  173. Always be open to better tools and keep them up

    to date @onishiweb
  174. Keep testing consistent @onishiweb

  175. Benchmarks

  176. 4983 4.783s 33/100 $$$$$ Meetup 1658 1.387s 92/100 $ FEL

    1379 1.287s 99/100 $ WebPerf
  177. https:/ /www.webpagetest.org/result/161030_PH_PTH/

  178. Make sure you’re adjusting for the right metric

  179. None
  180. None
  181. Adam Onishi LDN WebPerf @onishiweb Thanks!

  182. Reading list / Thanks Pro WordPress Theme Development by Adam

    Onishi http:/ /www.apress.com/9781430259145 Designing for Performance by Lara Hogan http:/ /shop.oreilly.com/product/0636920033578.do Designers Guide to Web Performance by Jon Yablonski: http:/ /jonyablonski.com/2016/designers-guide-to-web-performance-optimization/ Emoji’s from Emoji One http:/ /emojione.com/ Doorman icon by Dan Hetteix - The Noun Project https:/ /thenounproject.com/term/doorman/188002 Lighthouse icon by Carla Dias - The Noun Project https:/ /thenounproject.com/term/lighthouse/566292/ Slides and Paisley Shirt icon by Margarida Sousa