Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The Truth About Your Web App's Performance

1,005 views

Published on

The performance of your web app is obviously important. But how do you know your web app is performing well for all of your users? Out of the box tools provide us metrics, but most only provide an overall view. This case study of building the XFINITY X1 single-page web app will demonstrate what frontend performance data you should be gathering, how to gather it, and how to make sense of all that data.

Existing tools provide insight into the performance of our web applications, but there is not a single tool that gives you the full picture. You can fill these gaps by gathering the performance data of your actual users. In this talk, we'll walk through the parts of the W3C Navigation Timing, High Resolution Time & User Timing recommendations that you can easily take advantage of right now to collect important metrics (with the help of Open Source software). We'll determine the "types" of users you need to focus on to understand your web app, as well as what other factors could impact those individual users' experiences. And we'll make sure "Average Response Time" is never the primary focus of your metrics dashboard

Published in: Software
  • Be the first to comment

  • Be the first to like this

The Truth About Your Web App's Performance

  1. 1. The Truth About Your Web App’s Performance John Riviello @JohnRiv Distinguished Engineer, Comcast Interactive Media FOSSCON – August 22, 2015
  2. 2. John Riviello – The Truth Behind Your Web App’s Performance2
  3. 3. Frontend Performance Data 1. What do existing tools provide? 2. What data do you care about? 3. How do you gather that data? 4. What do you do with the data? John Riviello – The Truth Behind Your Web App’s Performance3
  4. 4. 1. Existing Tools 2. The Data You Care About 3. Gathering the Data 4. Analyzing the Data
  5. 5. Frontend Performance Data – Existing Tools WebPagetest.org John Riviello – The Truth Behind Your Web App’s Performance5
  6. 6. Frontend Performance Data – Existing Tools http://www.sitespeed.io/ https://run.sitespeed.io/ John Riviello – The Truth Behind Your Web App’s Performance11
  7. 7. Frontend Performance Data – Existing Tools https://github.com/sitespeedio/grunt-sitespeedio John Riviello – The Truth Behind Your Web App’s Performance16
  8. 8. Frontend Performance Data – Existing Tools https://github.com/macbre/phantomas https://github.com/gmetais/grunt-devperf John Riviello – The Truth Behind Your Web App’s Performance17
  9. 9. http://yellowlab.tools/
  10. 10. Frontend Performance Data – Existing Tools https://github.com/gmetais/grunt-yellowlabtools John Riviello – The Truth Behind Your Web App’s Performance21
  11. 11. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance22 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  12. 12. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance23 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  13. 13. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance24 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  14. 14. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance25 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  15. 15. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance26 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  16. 16. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance27 grunt.initConfig({ yellowlabtools: { production: { urls: [ 'https://xtv.comcast.net' ], failConditions: [ // The global score is the one calculated by Yellow Lab Tools 'fail if at least one url has a global score < 80/100', // Every single rule has its own score 'fail if at least one url has a rule score < 50/100', // You can ignore certain rules 'ignore iframesCount', // You can check a metric instead of the score by omitting '/100' 'fail if at least one url has a domElementsCount > 2000' ] } } });
  17. 17. Contribute to Open Source: https://github.com/gmetais/YellowLabTools
  18. 18. "RUM" by Tom B is licensed under CC BY-NC-SA 2.0
  19. 19. Real User Monitoring "yes, that's a rum filled coconut." by Brandon King is licensed under CC BY-NC 2.0 / Color adjusted from original
  20. 20. Frontend Performance Data – Existing Tools John Riviello – The Truth Behind Your Web App’s Performance31
  21. 21. http://www.appdynamics.com/product/browser-real-user-monitoring/
  22. 22. http://docs.newrelic.com/docs/new-relic-browser/page-load-timing-process
  23. 23. https://docs.newrelic.com/docs/browser/new-relic-browser/browser-agent-apis/manually-reporting-page-load-timing-data
  24. 24. https://ruxit.com/features/real-user-monitoring.html
  25. 25. https://github.com/bugsnag/bugsnag-js https://github.com/getsentry/raven-js
  26. 26. 1. Existing Tools 2. The Data You Care About 3. Gathering the Data 4. Analyzing the Data
  27. 27. Real User Monitoring "yes, that's a rum filled coconut." by Brandon King is licensed under CC BY-NC 2.0 / Color adjusted from original
  28. 28. Illustration from http://www.w3.org/TR/navigation-timing/#processing-model John Riviello – The Truth Behind Your Web App’s Performance41
  29. 29. Illustration from http://www.w3.org/TR/navigation-timing/#processing-model John Riviello – The Truth Behind Your Web App’s Performance42
  30. 30. John Riviello – The Truth Behind Your Web App’s Performance44
  31. 31. John Riviello – The Truth Behind Your Web App’s Performance45
  32. 32. Frontend Performance Data – The Data You Care About John Riviello – The Truth Behind Your Web App’s Performance46
  33. 33. Frontend Performance Data – The Data You Care About Example Factors That Impact Performance: John Riviello – The Truth Behind Your Web App’s Performance47 • User authentication state •“Type” of user • Number of “items” returned • Flash SWF dependency
  34. 34. John Riviello – The Truth Behind Your Web App’s Performance48
  35. 35. http://mashable.com/2014/01/31/gmail-slow/ John Riviello – The Truth Behind Your Web App’s Performance49 “Gmail’s People Widget appears to be the cause of the sluggishness, which is, only affecting Gmail on the web Google says…This is noticeable when users open an email conversation with a large number of participants…”
  36. 36. Consider what other unique factors in your app may impact performance
  37. 37. 1. Existing Tools 2. The Data You Care About 3. Gathering the Data 4. Analyzing the Data
  38. 38. John Riviello – The Truth Behind Your Web App’s Performance52
  39. 39. Frontend Performance Data – Gathering the Data Marking Timestamps John Riviello – The Truth Behind Your Web App’s Performance53 Back in the day: > new Date().getTime(); 1399754123456 ECMAScript 5.1: > Date.now(); 1399754123456 Most modern browsers have a better option…
  40. 40. Frontend Performance Data – Gathering the Data W3C High Resolution Time John Riviello – The Truth Behind Your Web App’s Performance55 •DOMHighResTimeStamp is available via window.performance.now() •Provides the time with sub-millisecond accuracy •Measured relative to the navigationStart attribute of the PerformanceTiming interface •Not subject to system clock skew or adjustments (uses a monotonically increasing clock)
  41. 41. Frontend Performance Data – Gathering the Data W3C High Resolution Time – Sub-ms Example John Riviello – The Truth Behind Your Web App’s Performance56 > var dateTest = function() { var start = Date.now(), area = window.innerWidth*window.innerHeight; return Date.now() - start; }; dateTest(); 0 > var highResTest = function() { var start = window.performance.now(), area = window.innerWidth*window.innerHeight; return window.performance.now() - start; }; highResTest(); 0.01200000406242907
  42. 42. Frontend Performance Data – Gathering the Data W3C High Resolution Time – Monotonic Clock John Riviello – The Truth Behind Your Web App’s Performance57 Why do we care? “Most systems run a daemon which regularly synchronizes the time. It is common for the clock to be tweaked a few milliseconds every 15-20 minutes. At that rate about 1% of 10 second intervals measured would be inaccurate.” Source: Tony Gentilcore http://gent.ilcore.com/2012/06/better-timer-for-javascript.html
  43. 43. John Riviello – The Truth Behind Your Web App’s Performance58
  44. 44. John Riviello – The Truth Behind Your Web App’s Performance59
  45. 45. Browser Support
  46. 46. John Riviello – The Truth Behind Your Web App’s Performance66
  47. 47. John Riviello – The Truth Behind Your Web App’s Performance67
  48. 48. https://github.com/Comcast/Surf-N-Perf
  49. 49. User Timing vs. Surf-N-Perf "Hurricane Earl's Waves" by John Riviello is licensed under CC BY-NC-SA 2.0 / Color adjusted from original
  50. 50. Frontend Performance Data – Gathering the Data with Surf-N-Perf Setting & Getting a Mark John Riviello – The Truth Behind Your Web App’s Performance70 // User Timing API > window.performance.mark('foo'); > window.performance.getEntriesByName('foo'); [PerformanceMark ] duration: 0 entryType: "mark" name: "foo" startTime: 3323.620999988634 > window.performance.getEntriesByName('foo')[0].startTime; 3323.620999988634 // Surf-N-Perf > surfnperf.mark('foo'); > surfnperf.getMark('foo'); 3323.620999988634
  51. 51. Frontend Performance Data – Gathering the Data with Surf-N-Perf Navigation Timing Mark & User Mark Duration John Riviello – The Truth Behind Your Web App’s Performance71 // User Timing API > window.performance.mark('foo'); > window.performance.measure('page_load_to_foo', 'loadEventEnd', 'foo'); > window.performance.getEntriesByName('page_load_to_foo'); [PerformanceMeasure ] duration: 3201.620999988634 entryType: "measure" name: "page_load_to_foo" startTime: 122 > window.performance.getEntriesByName('page_load_to_foo')[0].duration; 3201.620999988634 // Surf-N-Perf > surfnperf.mark('foo'); > surfnperf.duration('loadEventEnd','foo'); 3202 > surfnperf.duration('loadEventEnd','foo',{decimalPlaces:3}); 3201.621
  52. 52. Frontend Performance Data – Gathering the Data with Surf-N-Perf Event Duration (i.e. 2 User Marks) John Riviello – The Truth Behind Your Web App’s Performance72 // User Timing API > window.performance.mark('barStart'); > window.performance.mark('barEnd'); > window.performance.measure('barEvent', 'barStart', 'barEnd'); > window.performance.getEntriesByName(’barEvent')[0].duration; 3512.499000004027 // Surf-N-Perf > surfnperf.eventStart('bar'); > surfnperf.eventEnd('bar'); > surfnperf.eventDuration('bar'); 3512 > surfnperf.eventDuration('bar',{decimalPlaces:12}); 3512.499000004027
  53. 53. Frontend Performance Data – Gathering the Data with Surf-N-Perf Custom Event Data John Riviello – The Truth Behind Your Web App’s Performance73 // Surf-N-Perf > surfnperf.eventStart('bar'); // surfnperf.eventEnd(KEY, CUSTOM_DATA_OBJECT); > surfnperf.eventEnd('bar', {baz:'qux'}); > surfnperf.getEventData('bar', 'baz'); "qux"
  54. 54. Frontend Performance Data – Gathering the Data with Surf-N-Perf Tying It Together with Backbone.fetch() John Riviello – The Truth Behind Your Web App’s Performance74 // Surf-N-Perf > var collection = new Backbone.Collection(); collection.url = '/get-data/'; surfnperf.eventStart('getData'); collection.fetch({ success: function(collection) { surfnperf.eventEnd('getData', {status:'success', items: collection.length}); }, error: function() { surfnperf.eventEnd('getData', {status:'error'}); }, }); > surfnperf.eventDuration('getData', {decimalPlaces:2}); 1464.75 > surfnperf.getEventData('getData', 'status'); "success" > surfnperf.getEventData('getData', 'items'); 33
  55. 55. Frontend Performance Data – Gathering the Data with Surf-N-Perf Custom Data (not tied to an event) John Riviello – The Truth Behind Your Web App’s Performance75 // Surf-N-Perf > surfnperf.setCustom('initialUrl', window.location.pathname); > surfnperf.getCustom('initialUrl'); "https://xtv.comcast.net/recent"
  56. 56. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance76 // Surf-N-Perf
  57. 57. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance77 > surfnperf.getNetworkTime(); // fetchStart to connectEnd
  58. 58. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance78 > surfnperf.getServerTime(); // requestStart to responseEnd
  59. 59. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance79 > surfnperf.getNetworkLatency(); // fetchStart to responseEnd
  60. 60. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance80 > surfnperf.getProcessingLoadTime(); // responseEnd to loadEventEnd
  61. 61. Frontend Performance Data – Gathering the Data with Surf-N-Perf Common Navigation Timing Measurements John Riviello – The Truth Behind Your Web App’s Performance81 > surfnperf.getFullRequestLoadTime(); // navigationStart to loadEventEnd
  62. 62. 1. Existing Tools 2. The Data You Care About 3. Gathering the Data 4. Analyzing the Data
  63. 63. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance83
  64. 64. Average Response Times are for Average Products
  65. 65. PERCENTILE (at a minimum)
  66. 66. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance86
  67. 67. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance87
  68. 68. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance88
  69. 69. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance89
  70. 70. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance90
  71. 71. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance91
  72. 72. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance92
  73. 73. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance93
  74. 74. Frontend Performance Data – Analyzing The Data John Riviello – The Truth Behind Your Web App’s Performance94
  75. 75. BONUS! What other front-end performance data should you focus on?
  76. 76. Frontend Performance Data – Additional Metrics Time to First Paint John Riviello – The Truth Behind Your Web App’s Performance96 ”Love for paint" by Derek Gavey is licensed under CC BY 2.0
  77. 77. Frontend Performance Data – Additional Metrics Time to First Paint John Riviello – The Truth Behind Your Web App’s Performance97 Internet Explorer: > window.performance.timing.msFirstPaint; 1434341969277 Google Chrome: > window.chrome.loadTimes(); Object { commitLoadTime: 1434341655.700179 connectionInfo: "http/1" finishDocumentLoadTime: 1434341656.208713 finishLoadTime: 1434341656.733739 ...
  78. 78. Frontend Performance Data – Additional Metrics Time to First Paint John Riviello – The Truth Behind Your Web App’s Performance98 Google Chrome (continued): firstPaintAfterLoadTime: 1434341657.201959 firstPaintTime: 1434341655.978471 navigationType: "Other" npnNegotiatedProtocol: "unknown" requestTime: 1434341655.141803 startLoadTime: 1434341655.570092 wasAlternateProtocolAvailable: false wasFetchedViaSpdy: false wasNpnNegotiated: false }
  79. 79. Frontend Performance Data – Additional Metrics Time to First Paint John Riviello – The Truth Behind Your Web App’s Performance99 Alternatives: -window.requestAnimationFrame() - Load of last non-async resource in <head> - Custom Metric (First Tweet, Hero Image, etc.) http://www.stevesouders.com/blog/2015/05/12/hero-image-custom-metrics/
  80. 80. Frontend Performance Data – Additional Metrics John Riviello – The Truth Behind Your Web App’s Performance101 Illustration from http://www.w3.org/TR/resource-timing/#processing-model window.performance.getEntriesByType("resource")
  81. 81. Frontend Performance Data – Additional Metrics John Riviello – The Truth Behind Your Web App’s Performance102 3rd Party Resource
  82. 82. Frontend Performance Data – Additional Metrics John Riviello – The Truth Behind Your Web App’s Performance103 3rd Party Resource with Timing-Allow-Origin: *
  83. 83. Recap
  84. 84. Frontend Performance Data – Recap John Riviello – The Truth Behind Your Web App’s Performance106 • Performance is a feature! • Measure first—at the 99th percentile • Leverage W3C Performance APIs • Log network latency, browser processing time, and the full webpage request & response • Log major app-specific events with details For Further Info & Feedback: Twitter: @JohnRiv GitHub: https://github.com/Comcast/Surf-N-Perf

×