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

Improving Web Performance w/ Resource Hints

Improving Web Performance w/ Resource Hints

Want to give a boost to your website performance? Have you tried using Resource Hints? With a potentially big reward for a relatively small amount of work, Resource Hints allow you to prioritize the load of critical assets, resulting in an optimal performance and improved user experience. We’ll step through the simple implementation details along with the impacts to performance. Then we’ll look at ways to automate the steps for long-lasting benefits with minimum maintenance overhead.

Avatar for Darren L Martin

Darren L Martin

October 18, 2019
Tweet

Other Decks in Programming

Transcript

  1. Why Performance? #PerfMatters Decrease Bounce Rate: • 53% of visits

    are likely to be abandoned if pages take longer than 3 seconds to load • 46% of people say that waiting for pages to load is what they dislike the most when browsing the web on mobile devices 5
  2. Why Performance? #PerfMatters Decrease Bounce Rate Increase Conversion Rate: •

    Mobile sites that load closer to 5 seconds earn up to 2x more mobile ad revenue than those whose sites load in 19 seconds, the average • 70% longer average sessions for sites that load in 5 seconds vs 19 seconds. 7
  3. What are Resource Hints? 11 W3C’s definition: “These primitives enable

    the developer, and the server generating or delivering the resources, to assist the user agent in the decision process of which origins it should connect to, and which resources it should fetch and preprocess to improve page performance.”
  4. Layman’s terms: “Resource Hints are a simple but effective way

    that web developers can help the browser to stay one step ahead of the user and keep pages fast.” What are Resource Hints? 12
  5. Network Browser request content from server. Content files are received.

    Performance: Network vs Render 13 Render (Run-time) Browser parses and executes retrieved content files.
  6. Network Browser request content from server. Content files are received.

    • Resource Hints Performance: Network vs Render 14 Render (Run-time) Browser parses and executes retrieved content files.
  7. DNS-Prefetch Tell the browser to perform a DNS lookup in

    the background <html> <head> ... <link rel="dns-prefetch" href="http://domain.com"> ... </head> <body> ... </body> </html> 17
  8. 18

  9. 19

  10. Preconnect Tell the browser to begin the connection handshake (DNS,

    TCP, TLS) in the background <html> <head> ... <link rel="preconnect" href="https://domain.com"> ... </head> <body> ... </body> </html> 22
  11. 23

  12. 27

  13. DNS-Prefetch & Preconnect Combining the two will allow the browsers

    which lack support to fall back to at least execute the DNS lookup <html> <head> ... <link rel="dns-prefetch preconnect" href="https://domain.com"> ... </head> <body> ... </body> </html> 28
  14. State of HTTPS Adoption “Majority of the world’s top million

    websites now use HTTPS” https://scotthelme.co.uk/alexa-top-1-million-analysis-august-2018/ 32
  15. State of HTTPS Adoption “Majority of the world’s top million

    websites now use HTTPS” https://scotthelme.co.uk/alexa-top-1-million-analysis-august-2018/ 33 “Majority of the world’s top million websites now use HTTPS” https://scotthelme.co.uk/alexa-top-1-million-analysis-august-2018/
  16. Preload Specify resources your page will need very soon, making

    sure they are available earlier in the page lifecycle 35
  17. Preload Specify resources your page will need very soon, making

    sure they are available earlier in the page lifecycle (Attributes: as) <html> <head> ... <link rel="preload" href="link/to/stylesheet.css" as="style"> ... </head> <body> ... </body> </html> 36
  18. Preload Specify resources your page will need very soon, making

    sure they are available earlier in the page lifecycle (Attributes: as, media) <html> <head> ... <link rel="preload" href="link/to/stylesheet.css" as="style" media="(max-width: 992px)"> ... </head> <body> ... </body> </html> 37
  19. Preload Specify resources your page will need very soon, making

    sure they are available earlier in the page lifecycle (Attributes: as, media, type) <html> <head> ... <link rel="preload" href="link/to/video.mp4" as="video" type="video/mp4"> ... </head> <body> ... </body> </html> 38
  20. Preload - Fonts Specify resources your page will need very

    soon, making sure they are available earlier in the page lifecycle (Attributes: as, media, type, crossorigin) <html> <head> ... <link rel="preload" href="link/to/font.woff2" as="font" type="font/woff2" crossorigin> ... </head> <body> ... </body> </html> 39
  21. 43

  22. 44

  23. 45

  24. Current View / Page Browser detects the preload directive before

    it detects the font URL within the stylesheet. 48 DOCUMENT: <head> <link rel=”dns-prefetch preconnect” href=”https://g.com” > ... <link rel=”stylesheet” href=”main.css” > <link rel=”preload” as=”font” href=”font.woff2”> </head> <body> ... <script src=”https://g.com/gmaps.js”></script> </body> MAIN.CSS: url(‘../link/to/font.woff2’)
  25. Current View / Page Browser detects the preload directive before

    it detects the font URL within the stylesheet. The font is loaded and available for use sooner. 49 DOCUMENT: <head> <link rel=”dns-prefetch preconnect” href=”https://g.com” > ... <link rel=”stylesheet” href=”main.css” > <link rel=”preload” as=”font” href=”font.woff2”> </head> <body> ... <script src=”https://g.com/gmaps.js”></script> </body> MAIN.CSS: url(‘../link/to/font.woff2’)
  26. Critical (Happy) Path Web: “The typical sequence of steps taken

    by a user to convert.” Network Performance: “Resources that must be loaded before the initial render.” 52
  27. Measuring Single View / Page: 1. WebPageTest (WPT) - External

    2. Lighthouse (LH) - Local (Browser Extension) 53
  28. Measuring to Identify Single View / Page: 1. WebPageTest (WPT)

    - External 2. Lighthouse (LH) - Local (Browser Extension) 54
  29. 55

  30. 56

  31. Measuring to Confirm Single View / Page: 1. WebPageTest (WPT)

    - External 2. Lighthouse (LH) - Local (Browser Extension) 57
  32. 58

  33. 59

  34. Prefetch Specify resources that will be needed for the next

    navigation, making sure they are available earlier 64
  35. Prefetch Specify resources that will be needed for the next

    navigation, making sure they are available earlier <html> <head> ... <link rel="prefetch" href="link/to/asset.extension" as="style|script|font|image|video" crossorigin> ... </head> <body> ... </body> </html> 65
  36. 66

  37. 67

  38. Future View / Page 68 DOCUMENT A: <head> <link rel=”preconnect”...

    > <link rel=”preload”... > <link rel=”stylesheet” ... > <link rel=”prefetch” href=”doc-b.css” as=”style”> </head> <body> ... <script … ></script> </body> DOCUMENT B: <head> <link rel=”preconnect”... > <link rel=”preload”... > ... <link rel=”stylesheet” href=”doc-b.css”> </head> <body> ... <script ...></script> </body> Page A Page B Cache
  39. Future View / Page 69 DOCUMENT A: <head> <link rel=”preconnect”...

    > <link rel=”preload”... > <link rel=”stylesheet” ... > <link rel=”prefetch” href=”doc-b.css” as=”style”> </head> <body> ... <script … ></script> </body> DOCUMENT B: <head> <link rel=”preconnect”... > <link rel=”preload”... > ... <link rel=”stylesheet” href=”doc-b.css”> </head> <body> ... <script ...></script> </body> Page A Page B Cache
  40. Dynamically Injected - Prefetch // w3c-snippet.js var hint = document.createElement("link");

    hint.rel = "prefetch"; hint.as = "document"; hint.href = "/article/part3.html"; document.head.appendChild(hint); 70
  41. 71

  42. 72

  43. 73

  44. Team Search - Critical Assets - Hashed // team-search-assets.js [

    "main.7e86b45a.min.css", "main.c8784e3d8daef15f5712.min.js", "vendor.b207424b.min.css", "vendor.13a88024ceaf166c1980.min.js" ] 78
  45. Webpack - Asset Manifest Plugin $ npm install --save-dev webpack-manifest-plugin

    // webpack.config.js var ManifestPlugin = require('webpack-manifest-plugin'); module.exports = { plugins: [ new ManifestPlugin() ] }; 79
  46. Webpack - Asset Manifest JSON // team-search-asset-manifest.json { "main.css": "main.7e86b45a.min.css",

    "main.js": "main.c8784e3d8daef15f5712.min.js", "runtime.js": "runtime.69b7851664c8474c1ab4.min.js", "vendor.css": "vendor.b207424b.min.css", "vendor.js": "vendor.13a88024ceaf166c1980.min.js" } 80
  47. Prefetch - Injected at Runtime var doc = window.document, docHead

    = doc.head; var assetManifestObj = JSON.parse(<<assetManifest.json>>); var path = 'path/to/team-search/dist/bundle/'; Object.keys(assetManifestObj).forEach(function(assetName) { var linkElem = doc.createElement("link"); linkElem.rel = "prefetch"; linkElem.as = "<<script | style>>"; linkElem.href = path + assetManifestObj[assetName]; docHead.appendChild(linkElem); }); 81
  48. Puppeteer - Scripting const puppeteer = require('puppeteer'); (async () =>

    { const browser = await puppeteer.launch(); const page = await browser.newPage(); const start = performance.now(); await page.goto('https://www.store.google.com/landingpage'); await page.goto('https://www.store.google.com/productpage'); // click the buy button, which triggers overlay basket await page.click('#buy_btn'); // wait until basket overlay is shown await page.waitFor('#close_btn'); await page.goto('https://www.store.google.com/basket'); await page.goto('https://www.store.google.com/checkout'); console.log('Flow took ' + parseInt((performance.now() - start)/1000) + ' seconds'); await browser.close(); })(); 93
  49. “Guess.js uses a technique called predictive prefetching. By consuming data

    from an analytics source, such as Google Analytics, Guess.js enables our web applications to prefetch resources only when they are likely to be needed, considering the user's behavior.” 96
  50. 97

  51. Tools - Guess.js “Guess.js uses a technique called predictive prefetching.

    By consuming data from an analytics source, such as Google Analytics, Guess.js enables our web applications to prefetch resources only when they are likely to be needed, considering the user's behavior.” 98
  52. 99

  53. 100

  54. Resource Hints 1. DNS-Prefetch 2. Preconnect 3. Preload 4. Prefetch

    5. 101 Current View / Page Future View / Page
  55. Resource Hints 1. DNS-Prefetch 2. Preconnect 3. Preload 4. Prefetch

    5. Prerender 102 Current View / Page Future View / Page
  56. Resource Hints 1. DNS-Prefetch 2. Preconnect 3. Preload 4. Prefetch

    5. Prerender 103 Current View / Page Future View / Page
  57. Prerender Tell the browser to render the specified page in

    the background, speeding up page load as the user navigates to it <html> <head> ... <link rel="prerender" href="//url/to/page"> ... </head> <body> ... </body> </html> 104
  58. 105

  59. Resource Hints 1. DNS-Prefetch 2. Preconnect 3. Preload 4. Prefetch

    5. Prerender* * deprecated 106 Current View / Page Future View / Page
  60. 107

  61. 108

  62. Resource Hints 1. DNS-Prefetch 2. Preconnect 3. Preload 4. Prefetch

    5. Prerender* * deprecated use with caution 109 Current View / Page Future View / Page
  63. Summary & Next Steps 1. Performance is a feature 2.

    Define Critical (Happy) Path - Analyze user behavior 3. Automate Implementation: a. Frontend Tooling (Asset Manifest JSON) b. Third-party (quicklink, Guess.js) 4. Measure Consistently: a. Single View / Page - WPT or LH b. End-to-End - WPT or Puppeteer c. Set a Performance Budget 5. Performance Checklist (https://web.dev/fast) 110