The Hitchhiker's Guide to the Front-End Performance, 2019 edition

The Hitchhiker's Guide to the Front-End Performance, 2019 edition

97d21da8e0ffa8f81218a293482c253a?s=128

Matheus

March 16, 2019
Tweet

Transcript

  1. The Hitchhiker's Guide to the Front-End Performance The Hitchhiker's Guide

    to the Front-End Performance 2019 EDITION
  2. ˜ I’m from… ˜

  3. None
  4. None
  5. None
  6. !!!

  7. What do we know about perf? What do we know

    about perf?
  8. ˜ GZIP everything ˜ Minify both CSS and JS ˜

    HTML must be compressed ˜ CSS goes on <head> ˜ JS goes lastly on </body> ˜ Optimize all the images (e.g. svgo)
  9. Issues I was facing Issues I was facing

  10. ˜ What I do at …

  11. ˜ JavaScript ˜

  12. "Write modern, idiomatic JavaScript, and let the JavaScript engine worry

    about making it fast." - Mathias Bynens, BrazilJS 2018
  13. ˜ JavaScript ˜

  14. Before version 5.9 of V8 came out, the engine used

    two compilers: ˜ Full Codegen A simple and very fast compiler that produced simple and relatively slow machine code ˜ Crankshaft A more complex (Just-In-Time) optimizing compiler that produced highly-optimized code
  15. Optimization Killers

  16. Optimization Killers ~ Generators and async functions ~ for-of and

    destructuring ~ try-catch and try-finally ~ Compound let or const assignment ~ Object literals that contain __proto__, or get or set declarations. ~ debugger or with statements ~ Literal calls to eval() ~ …
  17. Performance cliffs in Crankshaft (function good() {
 const start =

    Date.now();
 for (var i = 0; i < 1e8; i++) {}
 console.log(Date.now() - start);
 })(); ˜80ms (function bad() {
 const start = Date.now();
 for (var i = 0; i < 1e8; i++) {}
 console.log(Date.now() - start);
 const whatever = 1;
 })(); ˜230ms
  18. Performance cliffs in Crankshaft (function good() {
 const start =

    Date.now();
 for (var i = 0; i < 1e8; i++) {}
 console.log(Date.now() - start);
 })(); (function bad() {
 const start = Date.now();
 for (var i = 0; i < 1e8; i++) {}
 console.log(Date.now() - start);
 const whatever = 1;
 })(); ˜3x slowdown with Crankshaft
  19. None
  20. The new execution pipeline is built on top of Ignition,

    V8’s interpreter, and TurboFan, V8’s newest optimizing compiler.
  21. Optimization Killers ~ Generators and async functions ~ for-of and

    destructuring ~ try-catch and try-finally ~ Compound let or const assignment ~ Object literals that contain __proto__, or get or set declarations. ~ debugger or with statements ~ Literal calls to eval() ~ …
  22. 60% faster web developer tools http://v8project.blogspot.com/2017/11/web-tooling-benchmark.html

  23. https://twitter.com/popeindustries/status/895575424406867968

  24. "Write modern, idiomatic JavaScript, and let the JavaScript engine worry

    about making it fast." - Mathias Bynens, BrazilJS 2018
  25. None
  26. None
  27. ˜ fixing perf issues be like ˜

  28. ˜ fixing perf issues be like ˜

  29. ˜ Problems ˜

  30. ˜ #1 ˜ Critical Resources Late Delivered

  31. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  32. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  33. <link rel="preconnect" href="https://fonts.googleapis.com/" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> ˜ What

    says… ˜ What can $% do…
  34. ˜ What it does… Preconnect allows the browser to setup

    early connections before an HTTP request is actually sent to the server. This includes: ˜ DNS lookups ˜ TLS negotiations ˜ TCP handshakes This in turn: ✔ Eliminates roundtrip latency ✔ Saves time for users
  35. ˜ Bring me the ! 100MS 200MS 300MS 400MS 500MS

    600MS 700MS HTML CSS FONT 1 FONT 2 Fonts start loading Fonts rendered
  36. ˜ Bring me the ! 100MS 200MS 300MS 400MS 500MS

    600MS 700MS HTML CSS FONT 1 FONT 2 Fonts start loading Fonts rendered FONT 1 FONT 2
  37. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  38. <link rel="preload" href="https://example.com/fonts/font.woff" as="font" crossorigin> ˜ What says… ˜ What

    can $% do…
  39. ˜ What it does… Some of the benefits of the

    preload directive include: ✔ Gives the browser the ability to determine the resource type (it can tell if the same resource can be reused in the future) ✔ The browser can determine if the request is compliant with the content security policy ✔ The browser can send the appropriate accept headers based on resource type
  40. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  41. ˜ What it does… ✔ Fetch resources in the background

    (idle time) ✔ Store them in the browser’s cache It can be:
  42. Link Prefetching DNS Prefetching Prerendering

  43. Link Prefetching DNS Prefetching Prerendering ˜ What it does… Allows

    the browser to fetch resources, store them in cache, assuming that the user will request them. <link rel="prefetch" href="/uploads/images/pic.png"> ˜ What can $% do…
  44. Link Prefetching DNS Prefetching Prerendering ˜ What it does… Allows

    the browser to perform DNS lookups on a page in the background while the user is browsing. <link rel=“dns-prefetch” href="#$fonts.googleapis.com"> ˜ What can $% do…
  45. Link Prefetching DNS Prefetching Prerendering ˜ What it does… Allows

    the browser to render the entire page in the background, all the assets of a document. <link rel=“prerender” href=“https://xandaviao.com.br/”> ˜ What can $% do…
  46. Link Prefetching DNS Prefetching Prerendering ˜ What it does… Allows

    the browser to render the entire page in the background, all the assets of a document. <link rel=“prerender” href=“https://xandaviao.com.br/”> ˜ What can $% do… ⚠ ❌ ❌ ⚠
  47. Link Prefetching DNS Prefetching Prerendering ˜ What it does… Allows

    the browser to render the entire page in the background, all the assets of a document. <link rel=“prerender” href=“https://xandaviao.com.br/”> ˜ What can $% do… ✘ You want to be more careful with prerendering as it is resource heavy and can cause bandwidth waste, especially on mobile devices
  48. https://wicg.github.io/priority-hints/

  49. %%%& A script is to be loaded with critical importance

    as it is necessary for the core user experience ''( <script src=foo importance=critical> %%%& An image is to be loaded with high importance. It could be important but not critical to the overall experience loading up. ''( <img src=foo importance=high> %%%& It can be used to indicate low importance/non-blocking style which isn't impacting the core experience. ''( <link rel=stylesheet href=foo importance=low>
  50. #$ First import(/* webpackPrefetch: 3 */ "assets/images/foo.jpg"); #$ Second import(/*

    webpackPrefetch: 2 */ "modules/foo"); #$ Last import(/* webpackPrefetch: 1 */ “modules/bar");
  51. Preloaded Chunk Prefetched Chunk X

  52. Preloaded Chunk Prefetched Chunk X ˜ Starts loading in parallel

    to the parent chunk ˜ Focuses on current navigation ˜ Fetches resources with high-priority ˜ Is instantly downloaded ˜ Starts after the parent chunk finish ˜ Focuses on fetching resources for the next navigation ˜ Fetches resources with low priority ˜ Is downloaded in browser idle time
  53. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  54. ˜ #2 ˜ Blocked First Paint

  55. ˜ Avoid invisible text while web fonts are loading ˜

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  56. ˜ Avoid invisible text while web fonts are loading ˜

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  57. ˜ What says… ˜ What can $% do… @font-face {

    font-family: "Open Sans Regular"; src: url(“./OpenSans-Regular-BasicLatin.woff2") format("woff2"); font-display: swap; }
  58. ˜ What says… ˜ What can $% do… @font-face {

    font-family: "Open Sans Regular"; src: url(“./OpenSans-Regular-BasicLatin.woff2") format("woff2"); font-display: swap; } ˜ What it does… The initial font displayed is the first system font in the stack. When the custom font has loaded, it will kick in and replace the system font that was initially displayed.
  59. ˜ Avoid invisible text while web fonts are loading ˜

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  60. ˜ What says… ˜ What can $% do… https://github.com/addyosmani/critical

  61. ˜ Avoid invisible text while web fonts are loading ˜

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  62. https://rauchg.com/2014/7-principles-of-rich-web-applications

  63. https://nextjs.org

  64. ˜ Avoid invisible text while web fonts are loading ˜

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  65. ˜ #3 ˜ Bloated Pages

  66. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  67. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  68. Bundlephobia Import Cost for VSCode Webpack Bundle Analyzer

  69. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  70. 1.8s bootup 0.78s bootup ˜ What says… ˜ What can

    $% do…
  71. 1.8s bootup 0.78s bootup ˜ What says… ˜ What can

    $% do… 56% faster
  72. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  73. https://github.com/GoogleChromeLabs/webpack-libs-optimizations

  74. None
  75. None
  76. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  77. ˜ #4 ˜ Unnecessary Resources

  78. ˜ Compress (gzip, brotli)

  79. ˜ -30%

  80. None
  81. None
  82. ⚠ ❌ ❌ ⚠

  83. ˜ Compress (gzip, brotli)

  84. ˜ #5 ˜ Unused Code

  85. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  86. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  87. 95% unused

  88. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  89. https://github.com/purifycss/purifycss

  90. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  91. (+ jest-image-snapshot)

  92. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  93. ˜ #6 ˜ Unoptimized Images

  94. ˜ Optimize images ˜ Use lighter formats ˜ Use responsive

    images
  95. ˜ Optimize images ˜ Use lighter formats ˜ Use responsive

    images
  96. ˜ What says…

  97. ˜ GUI ˜ ImageOptmin (Mac) XNConvert (Cross-platform) ˜ Build ˜

    imagemin libvips ˜ CDN ˜ Cloudinary Imgix Fastly Akamai ˜ CDN ˜ (self-hosted) Thumbor ImageFlow ˜ What can $% do…
  98. ˜ GUI ˜ ImageOptmin (Mac) XNConvert (Cross-platform) ˜ Build ˜

    imagemin libvips ˜ CDN ˜ Cloudinary Imgix Fastly Akamai ˜ CDN ˜ (self-hosted) Thumbor ImageFlow
  99. ˜ What it does…

  100. ˜ Optimize images ˜ Use lighter formats ˜ Use responsive

    images
  101. <img src="banda_magnificos.gif"> 7.3mb <video autoplay muted playinline> <source src="banda_magnificos.mp4" type="video/mp4">

    </video> 1.3MB <video autoplay muted playinline> <source src=“banda_magnificos.webm” type=“video/webm"> </video> 960kb 80%+ savings
  102. ˜ Optimize images ˜ Use lighter formats ˜ Use responsive

    images
  103. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

  104. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

  105. https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

  106. None
  107. 4G+ (Video) ˜1mb 2G-3G (Static Image) ˜30kb

  108. ˜ Optimize images ˜ Use lighter formats ˜ Use responsive

    images
  109. ˜ #7 ˜ Wasted Renders

  110. None
  111. Virtualizing a list of items involves maintaining a window and

    moving that window around your list. "How does windowing work?" by Brian Vaughn
  112. https://github.com/bvaughn/react-virtualized

  113. 10K items wo/ virtualization 10K items w/ virtualization X

  114. w/ virtualization X wo/ virtualization "Rendering large lists with react-window"

    by Addy Osmani
  115. w/ virtualization X wo/ virtualization "Rendering large lists with react-window"

    by Addy Osmani
  116. w/ virtualization X wo/ virtualization ˜242.7ms ˜2.4ms "Rendering large lists

    with react-window" by Addy Osmani
  117. ˜ Use referentially equal stuff ˜ Use PureComponent/memo (when it

    makes sense) ˜ (In the future) Take benefit from time slicing ˜ Take benefit from techniques like windowing
  118. "In God we trust; all others must bring data." -

    W. Edwards Deming
  119. ˜ Senior Software Engineer, Front- End @beakyn ˜ @ythecombinator on

    the webs ˜ addicted to emojis, memes and beer
  120. https://speakerdeck.com/ ythecombinator/the-hitchhiker-s-guide-to-the-front-end-performance-2019-edition

  121. None
  122. Thanks Thanks