Speed Index, explained

Speed Index, explained

In the land of web performance metrics, Speed Index is one of the most promising and robust ones around. Taking the visual progress on the user's screen into account instead of merely relying on navigation timings, it promises to give real feedback on the user experience of your website.

But is it really the silver bullet? What's the catch? Can we even "cheat" on getting a better score? In this talk, we will get to the bottom of Speed Index:

– We will learn how Speed Index is calculated and what you need to measure your own site's Speed Index
– We will see which pain points Speed Index tackles, and what you can do to optimize your site to get a better score
– We learn where the downsides of this metric are and if it should be of any concern to you
– Last, but not least, we will check how we can overcome those downsides with additional, non-disruptive monitoring to get an even better view of your site's performance.

187d92c9284160ad908885ab096f5209?s=128

Stefan Baumgartner

November 19, 2015
Tweet

Transcript

  1. Speed Index, Explained! Stefan Baumgartner | @ddprrt https://speakerdeck.com/ddprrt/speed-index-explained

  2. The page has to load in under 3 seconds

  3. None
  4. It works on my machine!

  5. None
  6. The Dothraki have no word for “works on my machine”

  7. Use metrics!

  8. loading document.readyState loading DOMContentLoaded window.onload

  9. window.performance.timing

  10. None
  11. Speed Index

  12. ∫ 1 - visuallycomplete/100 0 end

  13. What does this mean?

  14. None
  15. None
  16. None
  17. None
  18. None
  19. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  20. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  21. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  22. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  23. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  24. Visually complete (%) 0 25 50 75 100 Time in

    Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s
  25. So, how’s difference calculated?

  26. - =

  27. 6% difference

  28. 5% difference

  29. this is not good for the user this is

  30. None
  31. None
  32. Baseline JPEG 10%

  33. Baseline JPEG 10% 50%

  34. Baseline JPEG 10% 50% 100%

  35. Gotcha!

  36. Baseline JPEG If the image loads gradually over 1 second,

    it has a SpeedIndex of 500
  37. Progressive JPEG 10% 50% 100%

  38. Progressive JPEG The image is already ~77% complete at the

    beginning (it’s 23% different)
  39. Progressive JPEG So if it loads gradually over 1 second,

    it has a SpeedIndex of 113
  40. Some tricks …

  41. Webfonts

  42. Modern browser? Supports WOFF? Font in Storage Show Font Pre-Render

  43. Modern browser? Supports WOFF? Font in Storage Show Font No

    Font http://crocodillon.com/blog/non-blocking-web-fonts-using-localstorage Pre-Render
  44. localStorage available? Download Font Save in localStorage Show Font No

    Font http://crocodillon.com/blog/non-blocking-web-fonts-using-localstorage Post-Render
  45. Critical Path CSS

  46. None
  47. <link rel=“stylesheet” href=“main.css”> blocking!

  48. <link rel=“stylesheet” href=“main.css”> blocking! <script src=“main.js”> blocking!

  49. <link rel=“stylesheet” href=“main.css”> blocking! <script src=“main.js”> blocking! start render

  50. <link rel=“stylesheet” href=“main.css”> blocking! <script src=“main.js”> blocking! start render?

  51. <style> … </style> … <script> loadCSS(‘main.css’) </script> <script src=“main.js”>

  52. <style> … </style> … <script> loadCSS(‘main.css’) </script> <script src=“main.js”>

  53. <style> … </style> … <script> loadCSS(‘main.css’) </script> <script src=“main.js”>

  54. None
  55. None
  56. I’m not 100% happy with Critical Path CSS

  57. None
  58. None
  59. None
  60. There is still one thing however…

  61. Speed Index should give you an idea how the user

    feels when using your website
  62. … so why is everything done by a machine

  63. … so why is everything done by a machine

  64. None
  65. None
  66. None
  67. None
  68. None
  69. Let’s do it on the client!

  70. GetRects(); GetRectTimings(); GetFirstPaint(); GetFontTime(); CalculateVisualProgress(); CalculateSpeedIndex();

  71. GetRects(); GetRectTimings(); Get the visible rectangle for the things we

    care about. Get the timings of the resources inside
  72. window.performance.timing

  73. window.performance.timing getEntriesByType(‘resource’)

  74. None
  75. None
  76. None
  77. GetFirstPaint(); Calculate the timing when the browser painted first.

  78. // IE and Edge window.performance.timing.msFirstPaint // Chropera var times =

    window.chrome.loadTimes(); times.firstPaintTime
  79. // Every other browser var headURLs = {}; var headElements

    = doc.getElementsByTagName('head')[0].children; for (var i = 0; i < headElements.length; i++) { //get stylesheets and non-async scripts ... } // compare with resource timing var requests = win.performance.getEntriesByType("resource");
  80. GetFontTime(); Check all font resources and do resource timings …

  81. CalculateSpeedIndex(); Given the visual progress information, calculate the speed index.

  82. resource1 firstPaint resource3 resource4 endofPaint responseStart document font

  83. resource1 firstPaint resource3 resource4 endofPaint responseStart blank, 1 point per

    ms! gradually document font
  84. var now = ruxitApi.now(); var actionId = ruxitApi.enterAction( 'Speed Index',

    'speedIndex', now - RUMSpeedIndex(), null); ruxitApi.leaveAction(actionId, now); Tell your monitor solution
  85. https://github.com/ddprrt/RUM-SpeedIndex

  86. @ddprrt @dynatrace @ruxit