The Critical Request

The Critical Request

The Critical Request: An investigation into what blocks render
Serving a website seems pretty simple: send some HTML, the browser figures out what resources to load next. Then we wait patiently for the page to be ready.

However, browsers are complex and without a firm grasp on how resources are prioritized, fetched and rendered we’re needlessly penalising our customers with serious performance repercussions.

In this talk we’ll study how browsers determine which requests should be made, in what order, and what prevents the browser from rendering content quickly.

We’ll perform a live performance audit and demonstrate how to make meaningful improvements that go beyond current industry practices of “compress things and make less requests”. After this session people of all backgrounds should have a better understanding of where to start improving webperf immediately.

See the article that started the Critical Request - https://calibreapp.com/blog/critical-request/

1518538c2cd5fc2e54d4df083f1b3fa6?s=128

Ben Schwarz

June 21, 2018
Tweet

Transcript

  1. 3.

    Performance status quo Follow the rules you know and love

    • Serve less requests • Use compression everywhere possible (Brotli, GZip) • Bundle and minimise scripts (UglifyJS) • Use asset hashing (app-0ff97b5.js), with “forever” cache headers • Use CDNs (Fastly, Netlify, Cloudflare, Cloudfront)
  2. 6.
  3. 25.

    ← Critical requests A critical request is one that contains

    an asset that is essential to the content within the users viewport
  4. 26.

    Often, these are: 1. CSS for the elements 
 on

    the page 2. Fonts 3. Logo 4. A lead image ← Critical requests A critical request is one that contains an asset that is essential to the content within the users viewport
  5. 29.

    <!DOCTYPE html> <html> <head> <title>My website </title> <link rel="stylesheet" media="screen"

    href="/css/app.css" /> <script src="app.js" async> </script> </head> <body> … Resource queuing
  6. 30.

    <!DOCTYPE html> <html> <head> <title>My website </title> <link rel="stylesheet" media="screen"

    href="/css/app.css" /> <script src="app.js" async> </script> </head> <body> … Resource queuing Queue
  7. 31.

    <!DOCTYPE html> <html> <head> <title>My website </title> <link rel="stylesheet" media="screen"

    href="/css/app.css" /> <script src="app.js" async> </script> </head> <body> … app.css Resource queuing Queue
  8. 32.

    <!DOCTYPE html> <html> <head> <title>My website </title> <link rel="stylesheet" media="screen"

    href="/css/app.css" /> <script src="app.js" async> </script> </head> <body> … app.css app.js Resource queuing Queue
  9. 33.

    <!DOCTYPE html> <html> <head> <title>My website </title> <link rel="stylesheet" media="screen"

    href="/css/app.css" /> <script src="app.js" async> </script> </head> <body> … app.css app.js font.woff Resource queuing Queue
  10. 36.
  11. 37.
  12. 38.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest … and how they are referenced
  13. 39.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) … and how they are referenced
  14. 40.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) • Styles (Highest) … and how they are referenced
  15. 41.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) • Styles (Highest) • Images (Low or Medium) … and how they are referenced
  16. 42.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) • Styles (Highest) • Images (Low or Medium) • XHR/Fetch (High) … and how they are referenced
  17. 43.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) • Styles (Highest) • Images (Low or Medium) • XHR/Fetch (High) • Fonts (Highest) … and how they are referenced
  18. 44.

    app.css app.js font.woff Assets are prioritised by type Queue Highest

    High Lowest • HTML (Highest) • Styles (Highest) • Images (Low or Medium) • XHR/Fetch (High) • Fonts (Highest) • Scripts (Low, Medium or High!) … and how they are referenced
  19. 45.

    Javascript request priorities For an in depth guide, see https://www.html5rocks.com/en/tutorials/speed/script-loading/

    by @jaffathecake <script src="name.js"> </script> High (when placed before <img>) Otherwise, Medium <script src=“name.js" async> </script> <script src=“name.js" defer> </script> <script src=“name.js" type=“module”> </script> Low Priority
  20. 47.

    How fonts are fetched 1. The stylesheet targets an element

    with a font declaration body { font-family: Calibre; }
  21. 48.

    How fonts are fetched 1. The stylesheet targets an element

    with a font declaration body { font-family: Calibre; } 2. The stylesheet has a corresponding @font-face declaration @font-face { font-family: "Calibre"; src: url("/fonts/calibre.woff2") format("woff2"), url("/fonts/calibre.woff") format("woff"); }
  22. 49.

    How fonts are fetched 1. The stylesheet targets an element

    with a font declaration body { font-family: Calibre; } 3. There is text to render 2. The stylesheet has a corresponding @font-face declaration @font-face { font-family: "Calibre"; src: url("/fonts/calibre.woff2") format("woff2"), url("/fonts/calibre.woff") format("woff"); }
  23. 56.
  24. 57.
  25. 59.

    <link rel=“preload” href=“font.woff” as=“font” crossorigin /> Preload Critical, essential resources.

    Required for fonts! HTML Link: <font.woff>; rel=preload; as=font; crossorigin As a HTTP Header
  26. 62.

    <link rel="preload" href="/lineto-circular-book-c.woff" crossorigin as="font" /> <link rel="preload" href="/lineto-circular-medium-c.woff" crossorigin

    as="font" /> <link rel="preload" href=“/lineto-circular-bold-c.woff" crossorigin as="font" /> Use preload for critical resources Every browser that supports preload also supports WOFF. Preload those!
  27. 63.

    HTML CSS Font Weight 1 Font Weight 2 Font Weight

    3 Network timeline Text gets rendered here Before preload 5-7 seconds until text is visible
  28. 64.

    HTML CSS Font Weight 1 Font Weight 2 Font Weight

    3 Network timeline After preload 2-3 seconds until text is visible
  29. 65.

    HTML CSS Font Weight 1 Font Weight 2 Font Weight

    3 Network timeline After preload 2-3 seconds until text is visible Text gets rendered here
  30. 66.

    @font-face { font-family: LLCircularWeb; src: url(/lineto-circular-black-c.woff) format("woff"); font-weight: 800; font-style:

    normal; font-display: swap;
 } Add font-display: swap “ Display the text until the web font has loaded, then swap it out.
  31. 67.

    HTML Network timeline Before font-display 2-3 seconds until text is

    visible HTML CSS Font Weight 1 Font Weight 2 Font Weight 3
  32. 68.

    HTML Network timeline Before font-display 2-3 seconds until text is

    visible HTML CSS Font Weight 1 Font Weight 2 Font Weight 3 Text gets rendered here
  33. 69.

    HTML CSS Font Weight 1 Font Weight 2 Font Weight

    3 Network timeline After font-display Text is always visible
  34. 70.

    HTML CSS Font Weight 1 Font Weight 2 Font Weight

    3 Network timeline After font-display Text is always visible Text gets rendered here
  35. 75.

    Audit improvement notes 1. Use <link rel=“preload” /> to preload

    essential fonts. 2. Use font-display: swap; to ensure text is always visible.
  36. 76.

    Audit improvement notes 1. Use <link rel=“preload” /> to preload

    essential fonts. 2. Use font-display: swap; to ensure text is always visible. 3. Have font fallbacks that look similar to avoid changes when webfonts load.
  37. 77.

    Audit improvement notes 1. Use <link rel=“preload” /> to preload

    essential fonts. 2. Use font-display: swap; to ensure text is always visible. 3. Have font fallbacks that look similar to avoid changes when webfonts load. 4. Use woff2, woff where possible.
  38. 81.

    Audit checklist 1. Test under poor conditions to highlight performance

    issues. 2. Use the performance panel to explore the relationship between render, asset fetching, paints and JavaScript execution.
  39. 82.

    Audit checklist 1. Test under poor conditions to highlight performance

    issues. 2. Use the performance panel to explore the relationship between render, asset fetching, paints and JavaScript execution. 3. Ensure critical requests are prioritised.
  40. 83.

    Audit checklist 1. Test under poor conditions to highlight performance

    issues. 2. Use the performance panel to explore the relationship between render, asset fetching, paints and JavaScript execution. 3. Ensure critical requests are prioritised. 4. Iterate from good to great.
  41. 84.

    Audit checklist 1. Test under poor conditions to highlight performance

    issues. 2. Use the performance panel to explore the relationship between render, asset fetching, paints and JavaScript execution. 3. Ensure critical requests are prioritised. 4. Iterate from good to great.
  42. 90.

    … Can we schedule some more performance work? I have

    no idea how long it’ll take but we’ll hope for the best! Your manager You, without a plan
  43. 94.
  44. 95.

    Performance workbook Estimated gain Achieved gain Difficulty Estimated cost Preload

    fonts 3 — 5 seconds FMP 3 seconds to FMP Easy Low Font-display: swap Instant text rendering Instant text rendering Easy Low
  45. 96.

    Performance workbook Estimated gain Achieved gain Difficulty Estimated cost Preload

    fonts 3 — 5 seconds FMP 3 seconds to FMP Easy Low Font-display: swap Instant text rendering Instant text rendering Easy Low Remove all webfonts Less download? ? Political hurdles with branding team
  46. 97.

    Performance workbook Estimated gain Achieved gain Difficulty Estimated cost Preload

    fonts 3 — 5 seconds FMP 3 seconds to FMP Easy Low Font-display: swap Instant text rendering Instant text rendering Easy Low Remove all webfonts Less download? ? Political hurdles with branding team Rewrite app in React ? ? Hard Very expensive
  47. 98.

    Performance workbook Estimated gain Achieved gain Difficulty Estimated cost Preload

    fonts 3 — 5 seconds FMP 3 seconds to FMP Easy Low Font-display: swap Instant text rendering Instant text rendering Easy Low Remove all webfonts Less download? ? Political hurdles with branding team Rewrite app in React ? ? Hard Very expensive Remove ads 10 seconds time to interactive improvement on mobile devices ? Medium All our revenue
  48. 99.

    Performance workbook Estimated gain Achieved gain Difficulty Estimated cost Preload

    fonts 3 — 5 seconds FMP 3 seconds to FMP Easy Low Font-display: swap Instant text rendering Instant text rendering Easy Low Remove all webfonts Less download? ? Political hurdles with branding team Rewrite app in React ? ? Hard Very expensive Remove ads 10 seconds time to interactive improvement on mobile devices ? Medium All our revenue Delete all Javascript No JS, no problems ? Easy
  49. 100.

    Sure Can we schedule some more performance work? I’ve summarised

    some research and ideas in this spreadsheet… I can run you through the details over a coffee? Your manager You, an intellectual
  50. 103.

    The performance advocate’s manifesto 1. Performance is a baseline requirement.

    2. Every addition has a cost, therefore it should have a value.
  51. 104.

    The performance advocate’s manifesto 1. Performance is a baseline requirement.

    2. Every addition has a cost, therefore it should have a value. 3. Performance testing should be automated.
  52. 105.

    The performance advocate’s manifesto 1. Performance is a baseline requirement.

    2. Every addition has a cost, therefore it should have a value. 3. Performance testing should be automated. 4. Draw conclusions and act on observed performance data.
  53. 106.

    The performance advocate’s manifesto 1. Performance is a baseline requirement.

    2. Every addition has a cost, therefore it should have a value. 3. Performance testing should be automated. 4. Draw conclusions and act on observed performance data.