effectively monitoring client-side performance: nephp2016
TRANSCRIPT
Performance Metric Sources
1. Observational data 2. Browser devtools 3. Browser reported metrics
• Navigation Timing API • Paint metrics • Custom Metrics
Navigation Timing API• navigationStart • unloadEventStart • unloadEventEnd • redirectStart • redirectEnd • fetchStart • domainLookupStart • domainLookupEnd • connectStart • connectEnd
• secureConnectionStart • requestStart • responseStart • responseEnd • domLoading • domInteractive • domContentLoadedEventStart • domContentLoadedEventEnd
• domComplete • loadEventStart • loadEventEnd
Navigation Timing API• navigationStart - navigation initiated • responseStart - first byte of doc from server • responseEnd - last byte of doc from server • domInteractive - HTML parsed, DOM constructed • domContentLoaded - DOM and CSSOM constructed • domComplete/load - all subresources loaded
Paint Metrics
window.performance.timing.msFirstPaint
window.chrome.loadTimes().firstPaintTime
Internet Explorer
Chrome
Custom Metricswindow.performance.mark(‘mainImageLoaded’)
window.performance .getEntriesByName(‘mainImageLoaded’)[0] .startTime
Sources for RUM Metrics1. Observational data 2. Browser devtools 3. Browser reported metrics
• Navigation Timing API • Paint metrics • Custom Metrics
Tools for RUM Metrics
• Custom JavaScript • Open source JS libraries
• github.com/lognormal/boomerang
Sources for Synthetic Metrics
1. Observational data 2. Browser devtools 3. Browser reported metrics
• Navigation Timing API • Paint metrics • Custom Metrics
Phantomas> phantomas http://reddit.com
{ "metrics": { "requests": 73, "bodySize": 580491, "contentLength": 629382, "timeToFirstByte": 94, "timeToLastByte": 105, "DOMqueries": 247, "firstPaint": 0, "domInteractive": 215, "domContentLoaded": 213, "domContentLoadedEnd": 355, "domComplete": 792, "httpsRequests": [ "https://www.reddit.com/", "https://www.redditstatic.com/reddit-init.en.qq9nT0inXvw.js", "https://www.redditstatic.com/reddit.en.xlHlxcJziiU.js", "https://www.redditstatic.com/reddit.ooBJpEoO9vY.css", "https://www.google-analytics.com/analytics.js" ] // … and more! } }
Phantomas> phantomas http://reddit.com
{ "metrics": { "requests": 73, "bodySize": 580491, "contentLength": 629382, "timeToFirstByte": 94, "timeToLastByte": 105, "DOMqueries": 247, "firstPaint": 0, "domInteractive": 215, "domContentLoaded": 213, "domContentLoadedEnd": 355, "domComplete": 792, "httpsRequests": [ "https://www.reddit.com/", "https://www.redditstatic.com/reddit-init.en.qq9nT0inXvw.js", "https://www.redditstatic.com/reddit.en.xlHlxcJziiU.js", "https://www.redditstatic.com/reddit.ooBJpEoO9vY.css", "https://www.google-analytics.com/analytics.js" ] // … and more! } }
Phantomas> phantomas http://reddit.com
{ "metrics": { "requests": 73, "bodySize": 580491, "contentLength": 629382, "timeToFirstByte": 94, "timeToLastByte": 105, "DOMqueries": 247, "firstPaint": 0, "domInteractive": 215, "domContentLoaded": 213, "domContentLoadedEnd": 355, "domComplete": 792, "httpsRequests": [ "https://www.reddit.com/", "https://www.redditstatic.com/reddit-init.en.qq9nT0inXvw.js", "https://www.redditstatic.com/reddit.en.xlHlxcJziiU.js", "https://www.redditstatic.com/reddit.ooBJpEoO9vY.css", "https://www.google-analytics.com/analytics.js" ] // … and more! } }
Phantomas> phantomas http://reddit.com
{ "metrics": { "requests": 73, "bodySize": 580491, "contentLength": 629382, "timeToFirstByte": 94, "timeToLastByte": 105, "DOMqueries": 247, "firstPaint": 0, "domInteractive": 215, "domContentLoaded": 213, "domContentLoadedEnd": 355, "domComplete": 792, "httpsRequests": [ "https://www.reddit.com/", "https://www.redditstatic.com/reddit-init.en.qq9nT0inXvw.js", "https://www.redditstatic.com/reddit.en.xlHlxcJziiU.js", "https://www.redditstatic.com/reddit.ooBJpEoO9vY.css", "https://www.google-analytics.com/analytics.js" ] // … and more! } }
Browser-Perf> browser-perf http://reddit.com --selenium=selenium.example.com
Browser-Perf> browser-perf http://reddit.com --selenium=selenium.example.com
Browser-Perf> browser-perf http://reddit.com --selenium=selenium.example.com
Browser-Perf> browser-perf http://reddit.com --selenium=selenium.example.com
Calculating Speed Index
1. Take the duration until the page is visually complete
2. Separate it into 100ms intervals 3. For each interval, assign it a “percent
visually complete” 4. Invert that percentage so it’s “percent
incomplete” or “percent remaining” 5. Multiply that by the interval length (100ms) 6. Sum all of the intervals. Speed Index!
• Aggregation • Data storage + queries • Visualization • Alerts + Notification
Storing and Monitoring
Reduce Noise
• Isolate third party scripts and external services
• Control conditional code paths (A/B tests, etc.)
Utilize Data
• Agree on performance metrics • Agree on performance goals • Allocate time and resources
to achieving these goals
Andrew Rota, .
@AndrewRota .
Thanks!Recommend Resources
• bit.ly/google_rails • bit.ly/webpagetest_docs • bit.ly/browser_perf • bit.ly/statsdcc • bit.ly/phantomas_js • graphite.readthedocs.io