-
-
Save pmeenan/5902672 to your computer and use it in GitHub Desktop.
// Support routines for automatically reporting user timing for common analytics platforms | |
// Currently supports Google Analytics, Boomerang and SOASTA mPulse | |
// In the case of boomerang, you will need to map the event names you want reported | |
// to timer names (for mPulse these need to be custom0, custom1, etc) using a global variable: | |
// rumMapping = {'aft': 'custom0'}; | |
(function() { | |
var wtt = function(n, t, b) { | |
t = Math.round(t); | |
if (t >= 0 && t < 3600000) { | |
// Google Analytics | |
if (!b && window['_gaq']) | |
_gaq.push(['_trackTiming', 'UserTimings', n, t]); | |
// Boomerang/mPulse | |
if (b && window['rumMapping'] && window.rumMapping[n]) | |
BOOMR.plugins.RT.setTimer(window.rumMapping[n], t); | |
} | |
}; | |
utReportRUM = function(b){ | |
var m = window.performance.getEntriesByType("mark"); | |
var lm={}; | |
for (i = 0; i < m.length; i++) { | |
g = 'usertiming'; | |
if (lm[g] == undefined || m[i].startTime > lm[g]) | |
lm[g] = m[i].startTime; | |
p = m[i].name.match(/([^\.]+)\.([^\.]*)/); | |
if (p && p.length > 2 && | |
(lm[p[1]] == undefined || | |
m[i].startTime > lm[p[1]])) | |
lm[p[1]] = m[i].startTime; | |
} | |
for (g in lm) | |
wtt(g, lm[g], b); | |
}; | |
utOnLoad = function() {utReportRUM(false);}; | |
if (window['addEventListener']) | |
window.addEventListener('load', utOnLoad, false); | |
else if (window['attachEvent']) | |
window.attachEvent('onload', utOnLoad); | |
// Boomerang/mPulse support | |
utSent = false; | |
BOOMR = window.BOOMR || {}; | |
BOOMR.plugins = BOOMR.plugins || {}; | |
BOOMR.plugins.UserTiming = { | |
init: function(config) {BOOMR.subscribe('page_ready', function(){ | |
if (!utSent) { | |
utReportRUM(true); | |
utSent=true; | |
BOOMR.sendBeacon(); | |
} | |
});}, | |
is_complete: function() {return utSent;} | |
}; | |
})(); |
/* | |
Strategically place: | |
markUserTime('some event'); | |
Through your code to get measurements for when various activities complete. It | |
will also generate timeline events so you can see them in Chrome's dev tools. | |
A good use case is to add them inline to sections of your site that are | |
above-the fold (right after the menu, right after the main story, etc) and also | |
in the onload handler for any critical above-the-fold images. | |
*/ | |
;(function () { | |
var w = typeof window != 'undefined' ? window : exports, | |
marks = []; | |
w.performance || (w.performance = {}); | |
w.performance.now || ( | |
w.performance.now = performance.now || performance.webkitNow || | |
performance.msNow || performance.mozNow); | |
if (!w.performance.now){ | |
var s = Date.now ? Date.now() : +(new Date()); | |
if (performance.timing && performance.timing) | |
s = performance.timing.navigationStart | |
w.performance.now = (function(){ | |
var n = Date.now ? Date.now() : +(new Date()); | |
return n-s; | |
}); | |
} | |
w.performance.mark || ( | |
w.performance.mark = | |
w.performance.webkitMark ? w.performance.webkitMark : | |
(function (l) { | |
marks.push({'name':l,'entryType':'mark','startTime':w.performance.now(),'duration':0}); | |
})); | |
w.performance.getEntriesByType || ( | |
w.performance.getEntriesByType = | |
w.performance.webkitGetEntriesByType ? w.performance.webkitGetEntriesByType : | |
(function (t) { | |
return t == 'mark' ? marks : undefined; | |
})); | |
}()); | |
window.markUserTime = function(l) { | |
var raf = window['requestAnimationFrame'] || | |
(function(callback){setTimeout(callback, 0);}); | |
raf(function(){ | |
window.performance.mark(l); | |
if (window['console'] && console['timeStamp']) | |
console.timeStamp(l); | |
}); | |
}; |
@pmeenan Out of curiosity, why is this step necessary?
if (t >= 0 && t < 3600000) {
https://gist.github.com/pmeenan/5902672#file-user-timing-rum-js-L9
Curiously enough, I left this step out, and am getting lots of IE9 responses that appear to be a timestamp, instead of the delta.
The spec says http://www.w3.org/TR/performance-timeline/#dom-performance-getentriesbytype that getEntriesByType
should always return a sequence. It seems like it would be more correct if the polyfill returned []
instead of undefined
when the type is not 'mark'. https://gist.github.com/edmund-huber/d3acd4d510d895cf860a#file-user-timing-js-L39
There is a bug in line 22:
if (performance.timing && performance.timing)
should probably be
if (w.performance.timing && w.performance.timing.navigationStart)
@jamischarles, the lognormal one is stable. RT plugin is opensource. UT isn't so much a plugin, nothing really to opensource, though I'm thinking of merging it into RT.
@bluesmoon Also, which repo is considered stable? Your fork, or lognormal, or another?