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

The Hitchhiker's Guide to the Front-End Perform...

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

Matheus Albuquerque

March 16, 2019
Tweet

More Decks by Matheus Albuquerque

Other Decks in Programming

Transcript

  1. !!!

  2. ˜ 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)
  3. "Write modern, idiomatic JavaScript, and let the JavaScript engine worry

    about making it fast." - Mathias Bynens, BrazilJS 2018
  4. 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
  5. 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() ~ …
  6. 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
  7. 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
  8. The new execution pipeline is built on top of Ignition,

    V8’s interpreter, and TurboFan, V8’s newest optimizing compiler.
  9. 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() ~ …
  10. "Write modern, idiomatic JavaScript, and let the JavaScript engine worry

    about making it fast." - Mathias Bynens, BrazilJS 2018
  11. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

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

    page (preload) ˜ Asset for future navigation (prefetch)
  13. ˜ 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
  14. ˜ Bring me the ! 100MS 200MS 300MS 400MS 500MS

    600MS 700MS HTML CSS FONT 1 FONT 2 Fonts start loading Fonts rendered
  15. ˜ 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
  16. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  17. ˜ 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
  18. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

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

    (idle time) ✔ Store them in the browser’s cache It can be:
  20. 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…
  21. 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…
  22. 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…
  23. 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… ⚠ ❌ ❌ ⚠
  24. 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
  25. %%%& 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>
  26. #$ First import(/* webpackPrefetch: 3 */ "assets/images/foo.jpg"); #$ Second import(/*

    webpackPrefetch: 2 */ "modules/foo"); #$ Last import(/* webpackPrefetch: 1 */ “modules/bar");
  27. 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
  28. ˜ Connecting to critical origins (preconnect) ˜ Asset for current

    page (preload) ˜ Asset for future navigation (prefetch)
  29. ˜ Avoid invisible text while web fonts are loading ˜

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

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

    font-family: "Open Sans Regular"; src: url(“./OpenSans-Regular-BasicLatin.woff2") format("woff2"); font-display: swap; }
  32. ˜ 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.
  33. ˜ Avoid invisible text while web fonts are loading ˜

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

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

    Reduce render blocking scripts and stylesheets ˜ Server-side render stuff
  36. ˜ Audit your assets regularly ˜ Code Split (Routes, Components,

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

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

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

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

    Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake
  41. ˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse

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

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

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

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

    Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests
  46. ˜ GUI ˜ ImageOptmin (Mac) XNConvert (Cross-platform) ˜ Build ˜

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

    imagemin libvips ˜ CDN ˜ Cloudinary Imgix Fastly Akamai ˜ CDN ˜ (self-hosted) Thumbor ImageFlow
  48. <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
  49. Virtualizing a list of items involves maintaining a window and

    moving that window around your list. "How does windowing work?" by Brian Vaughn
  50. ˜ 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
  51. ˜ Senior Software Engineer, Front- End @beakyn ˜ @ythecombinator on

    the webs ˜ addicted to emojis, memes and beer