performance monitoring for the new front end
DESCRIPTION
TRANSCRIPT
Performance Monitoring for the
New Front End
By Emily Nakashima, @eanakashima& Rachel Myers, @rachelmyers
bit.ly/ostrichandyak
Aka: Monitoring Single-Page App
Performance
Aka: SayGoodbye tothe Ostrich.
Aka: SayGoodbye tothe Ostrich.
The Agenda
I. Why Performance?
II. Burying our Head in the Sand
III.Epic Performance Monitoring Yak Shave
IV.The Future
I. Why Performance?
bit.ly/ostrichandyak
Most Performance is in the Front End
Back end Front end
Slow Pages Hurt
Slow Pages Hurt
• Bing: ⬆2s = ⬇4.3% revenue/user
Slow Pages Hurt
• Bing: ⬆2s = ⬇4.3% revenue/user
• Google: ⬆400ms = ⬇.59% searches/user
Slow Pages Hurt
• Bing: ⬆2s = ⬇4.3% revenue/user
• Google: ⬆400ms = ⬇.59% searches/user
• Yahoo: ⬆400ms = ⬇5-9% traffic
Fast Pages Help
Fast Pages Help
• Mozilla:
Fast Pages Help
• Mozilla:
• ⬇2.2s = ⬆15.4% Firefox downloads (+60M)
Fast Pages Help
• Mozilla:
• ⬇2.2s = ⬆15.4% Firefox downloads (+60M)
• Shopzilla:
Fast Pages Help
• Mozilla:
• ⬇2.2s = ⬆15.4% Firefox downloads (+60M)
• Shopzilla:
• conversion ⬆ 7 - 12%
Fast Pages Help
• Mozilla:
• ⬇2.2s = ⬆15.4% Firefox downloads (+60M)
• Shopzilla:
• conversion ⬆ 7 - 12%
• 2x sessions from Search Engine Marketing
Cumulative and Lasting Effects
Cumulative and Lasting Effects
• eBay:
Cumulative and Lasting Effects
• eBay:
• Beginning of experiment: ⬇.44% searches
Cumulative and Lasting Effects
• eBay:
• Beginning of experiment: ⬇.44% searches
• End of experiment:⬇.76% searches
Cumulative and Lasting Effects
• eBay:
• Beginning of experiment: ⬇.44% searches
• End of experiment:⬇.76% searches
• After correction: ⬇.21% searches
Cumulative and Lasting Effects
• eBay:
• Beginning of experiment: ⬇.44% searches
• End of experiment:⬇.76% searches
• After correction: ⬇.21% searches
• Strangeloop:
Cumulative and Lasting Effects
• eBay:
• Beginning of experiment: ⬇.44% searches
• End of experiment:⬇.76% searches
• After correction: ⬇.21% searches
• Strangeloop:
• Took 6 weeks for experiment group visits to recover
Why Performance: The bottom line.
II. Burying our Head in the Sand.
dinosaurs partying with cake and a new relic dashboard!
dinosaurs partying with cake and a new relic dashboard!
12 bijillion
Backbone: the Ostrich Killer
Screenshot of tablet site
Backbone: the Ostrich Killer
Screenshot of tablet site
dinosaurs partying with cake and a new relic dashboard!
dinosaurs partying with cake and a new relic dashboard!
A Diagnostic Slide
• Do you load content with ajax?
• Do you <3 any of these buzzwords?
Ember / Backbone / Angular / whatever-mvc
Turbolinks in Rails4
pjax/hijax
pushState
III. Epic Performance MonitoringYak Shave
Our old tools
• YSlow / PageSpeed Insights
• New Relic
• LogNormal
• WebPageTest
YSlow / PageSpeed
New Relic
New Relic
LogNormal
LogNormal
LogNormal
WebPageTest
WebPageTest
WebPageTest
Nope.
New things to track
• Feature load
• “Page” load
• Unresponsiveness (jank)
New things to track
• { featureName: loadTime }
• { pageName: loadTime }
• [ timestamp, timestamp, timestamp... ]
Surprise tools to the rescue.
• Google Analytics
• Circonus
Google Analytics
Google Analytics
Google Analytics
Google Analytics
The code to add tracking can be fairly straightforward:
_gaq.push([‘_trackTiming’, category, variable, time, opt_label, opt_sample]);
Circonus
Circonus
All together
Feature load
Feature loadTrackTiming = function(category, feature) { this.category = category; this.feature = feature; this.startTime = new Date().getTime(); this.endTime = null; return this;};
TrackTiming.prototype.startTime = new Date().getTime(); // shared startTime
TrackTiming.prototype.setEnd = function() { this.endTime = new Date().getTime(); return this;};
Feature loadTrackTiming.prototype.sendFeatureTiming = function() { var time = this.endTime - this.startTime; var twoMinutes = 1000 * 60 * 2; if (time < twoMinutes && time > 0) { window._gaq.push(['_trackTiming', this.category, this.feature, time]); } return this;};
var tt = new TrackTiming(); // init$(‘#myImg’).on('load', function() { tt.setEndTime().sendFeatureTiming();});
“Page” load
“Page” load
• Composed of many features.
• “Page” is loaded is called when sendFeatureTiming has been called for each feature.
“Page” loadTrackTiming.prototype.sendPageTiming = function(pageName) { var time = this.endTime - this.startTime;
window._gaq.push(['_trackTiming', 'custom_timings', pageName, time]);};
// ... set up feature tracking here ...
$.when(trackTiming1, trackTiming2).done( function() { tt.sendPageTiming(); }); // resolves when both timings are done
Unresponsiveness
Unresponsiveness
Unresponsiveness
• Hardest to manage observer effects.
• Strategy: look for moments when the browser isn’t free to take orders.
• Use setTimeout to set timestamps, and see how far apart they fall.
Unresponsivenessvar measurements = [];var now = new Date();
var checkTime = function(measurements) { var newNow = new Date(); measurements.push(newNow - now); now = newNow; setTimeout(checkTime,300);};
// collects an array of times:// measurements = [357,300,300,424,404,300]
IV. The Future
Recap: newthings to track
• Feature load
• “Page” load
• Unresponsiveness (jank)
Feature load
“Page” load// We modified our backbone app to always// call beforeRoute & afterRoute callbacks,// a low-config way to tracking loading.
var beforeRoute = function() { tt.resetPageTiming();};
var afterRoute = function() {var currentPage = window.location;tt.sendPageTiming(currentPage);
};
Unresponsiveness
Thanks!
@eanakashima & @rachelmyersbit.ly/ostrichandyak