Skip to content

Instantly share code, notes, and snippets.

@curlup
Forked from pmeenan/user-timing-rum.js
Last active August 29, 2015 14:20

Revisions

  1. @pmeenan pmeenan revised this gist Jul 11, 2013. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions user-timing-rum.js
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    // 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'])
  2. @pmeenan pmeenan revised this gist Jul 11, 2013. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion user-timing-rum.js
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,6 @@
    // rumMapping = {'aft': 'custom0'};
    (function() {
    var wtt = function(n, t, b) {
    console.log('Reporting ' + n + ' : ' + t);
    if (t >= 0 && t < 3600000) {
    // Google Analytics
    if (!b && window['_gaq'])
  3. @pmeenan pmeenan revised this gist Jul 11, 2013. 2 changed files with 9 additions and 6 deletions.
    9 changes: 6 additions & 3 deletions user-timing-rum.js
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    // rumMapping = {'aft': 'custom0'};
    (function() {
    var wtt = function(n, t, b) {
    console.log('Reporting ' + n + ' : ' + t);
    if (t >= 0 && t < 3600000) {
    // Google Analytics
    if (!b && window['_gaq'])
    @@ -43,9 +44,11 @@ BOOMR = window.BOOMR || {};
    BOOMR.plugins = BOOMR.plugins || {};
    BOOMR.plugins.UserTiming = {
    init: function(config) {BOOMR.subscribe('page_ready', function(){
    utReportRUM(true);
    utSent=true;
    BOOMR.sendBeacon();
    if (!utSent) {
    utReportRUM(true);
    utSent=true;
    BOOMR.sendBeacon();
    }
    });},
    is_complete: function() {return utSent;}
    };
    6 changes: 3 additions & 3 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -39,12 +39,12 @@ in the onload handler for any critical above-the-fold images.
    return t == 'mark' ? marks : undefined;
    }));
    }());
    markUserTime = (function(l) {
    window.markUserTime = function(l) {
    var raf = window['requestAnimationFrame'] ||
    (function(callback){setTimeout(callback, 0);});
    raf(function(){
    window.performance.mark(l);
    if (console && console.timeStamp)
    if (window['console'] && console['timeStamp'])
    console.timeStamp(l);
    });
    })();
    };
  4. @pmeenan pmeenan revised this gist Jul 11, 2013. 1 changed file with 52 additions and 0 deletions.
    52 changes: 52 additions & 0 deletions user-timing-rum.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    // 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) {
    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(){
    utReportRUM(true);
    utSent=true;
    BOOMR.sendBeacon();
    });},
    is_complete: function() {return utSent;}
    };
    })();
  5. @pmeenan pmeenan revised this gist Jul 11, 2013. 1 changed file with 0 additions and 63 deletions.
    63 changes: 0 additions & 63 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -47,67 +47,4 @@ markUserTime = (function(l) {
    if (console && console.timeStamp)
    console.timeStamp(l);
    });
    });

    // Support routines for automatically reporting user timing for common analytics platforms
    // Currently supports Google Analytics, Boomerang and SOASTA mPulse
    // In the case of mPulse, you will need to map the event names you want reported
    // to custom0, custom1, etc using a global variable:
    // mPulseMapping = {'aft': 'custom0'};
    (function() {
    var wtt = function(g, n, t, b) {
    if (t >= 0 && t < 3600000) {
    // Google Analytics
    if (!b && window['_gaq'])
    _gaq.push(['_trackTiming', g, n, t]);

    // Boomerang/mPulse
    if (b && window['BOOMR'] && BOOMR['plugins'] &&
    BOOMR.plugins['RT'] && BOOMR.plugins.RT['setTimer']) {
    if (window['mPulseMapping']) {
    if (window.mPulseMapping[n])
    BOOMR.plugins.RT.setTimer(window.mPulseMapping[n], t);
    } else {
    n = n.replace(/[^0-9a-zA-Z_]/g,'_');
    BOOMR.plugins.RT.setTimer(n, t);
    }
    }
    }
    };
    utSent = false;
    utReportRUM = function(b){
    var m = window.performance.getEntriesByType("mark");
    var lm={};
    for (i = 0; i < m.length; i++) {
    g = 'usertiming';
    n = m[i].name;
    p = n.match(/([^\.]+)\.([^\.]*)/);
    if (p && p.length > 2) {
    g = p[1];
    n = p[2];
    }
    if (lm[g] == undefined || m[i].startTime > lm[g])
    lm[g] = m[i].startTime;
    wtt(g, n, m[i].startTime, b)
    }
    for (g in lm)
    wtt('UserTimings', g, lm[g], b);
    if (b && !utSent && window['BOOMR'] && BOOMR.sendBeacon) {
    utSent = true;
    BOOMR.sendBeacon();
    }
    };
    utOnLoad = function() {utReportRUM(false);};
    if (window['addEventListener'])
    window.addEventListener('load', utOnLoad, false);
    else if (window['attachEvent'])
    window.attachEvent('onload', utOnLoad);

    // Boomerang/mPulse support
    BOOMR = window.BOOMR || {};
    BOOMR.plugins = BOOMR.plugins || {};
    BOOMR.plugins.UserTiming = {
    init: function(config) {BOOMR.subscribe('page_ready', function(){utReportRUM(true);});},
    is_complete: function() {return utSent;}
    };
    })();
  6. @pmeenan pmeenan revised this gist Jul 10, 2013. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion user-timing.js
    Original file line number Diff line number Diff line change
    @@ -67,8 +67,10 @@ var wtt = function(g, n, t, b) {
    if (window['mPulseMapping']) {
    if (window.mPulseMapping[n])
    BOOMR.plugins.RT.setTimer(window.mPulseMapping[n], t);
    } else
    } else {
    n = n.replace(/[^0-9a-zA-Z_]/g,'_');
    BOOMR.plugins.RT.setTimer(n, t);
    }
    }
    }
    };
  7. @pmeenan pmeenan revised this gist Jul 10, 2013. 1 changed file with 42 additions and 12 deletions.
    54 changes: 42 additions & 12 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -39,9 +39,8 @@ in the onload handler for any critical above-the-fold images.
    return t == 'mark' ? marks : undefined;
    }));
    }());

    markUserTime = (function(l) {
    var raf = window.requestAnimationFrame ||
    var raf = window['requestAnimationFrame'] ||
    (function(callback){setTimeout(callback, 0);});
    raf(function(){
    window.performance.mark(l);
    @@ -50,16 +49,35 @@ markUserTime = (function(l) {
    });
    });

    // Support routines for automatically reporting user timing for common analytics platforms
    // Currently supports Google Analytics, Boomerang and SOASTA mPulse
    // In the case of mPulse, you will need to map the event names you want reported
    // to custom0, custom1, etc using a global variable:
    // mPulseMapping = {'aft': 'custom0'};
    (function() {
    var wtt = function(g, n, t) {
    if (window._gaq)
    _gaq.push(['_trackTiming', g, n, t]);
    var wtt = function(g, n, t, b) {
    if (t >= 0 && t < 3600000) {
    // Google Analytics
    if (!b && window['_gaq'])
    _gaq.push(['_trackTiming', g, n, t]);

    // Boomerang/mPulse
    if (b && window['BOOMR'] && BOOMR['plugins'] &&
    BOOMR.plugins['RT'] && BOOMR.plugins.RT['setTimer']) {
    if (window['mPulseMapping']) {
    if (window.mPulseMapping[n])
    BOOMR.plugins.RT.setTimer(window.mPulseMapping[n], t);
    } else
    BOOMR.plugins.RT.setTimer(n, t);
    }
    }
    };
    utOnLoad = function() {
    utSent = false;
    utReportRUM = function(b){
    var m = window.performance.getEntriesByType("mark");
    var lm={};
    for (i = 0; i < m.length; i++) {
    g = 'user';
    g = 'usertiming';
    n = m[i].name;
    p = n.match(/([^\.]+)\.([^\.]*)/);
    if (p && p.length > 2) {
    @@ -68,14 +86,26 @@ utOnLoad = function() {
    }
    if (lm[g] == undefined || m[i].startTime > lm[g])
    lm[g] = m[i].startTime;
    wtt(g, n, m[i].startTime)
    wtt(g, n, m[i].startTime, b)
    }
    for (g in lm) {
    wtt('UserTimings', g, lm[g]);
    for (g in lm)
    wtt('UserTimings', g, lm[g], b);
    if (b && !utSent && window['BOOMR'] && BOOMR.sendBeacon) {
    utSent = true;
    BOOMR.sendBeacon();
    }
    };
    if (window.addEventListener)
    utOnLoad = function() {utReportRUM(false);};
    if (window['addEventListener'])
    window.addEventListener('load', utOnLoad, false);
    else if (window.attachEvent)
    else if (window['attachEvent'])
    window.attachEvent('onload', utOnLoad);

    // Boomerang/mPulse support
    BOOMR = window.BOOMR || {};
    BOOMR.plugins = BOOMR.plugins || {};
    BOOMR.plugins.UserTiming = {
    init: function(config) {BOOMR.subscribe('page_ready', function(){utReportRUM(true);});},
    is_complete: function() {return utSent;}
    };
    })();
  8. @pmeenan pmeenan revised this gist Jul 8, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -52,8 +52,8 @@ markUserTime = (function(l) {

    (function() {
    var wtt = function(g, n, t) {
    if (window._trackTiming)
    _trackTiming(g, n, t);
    if (window._gaq)
    _gaq.push(['_trackTiming', g, n, t]);
    };
    utOnLoad = function() {
    var m = window.performance.getEntriesByType("mark");
  9. @pmeenan pmeenan revised this gist Jul 7, 2013. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion user-timing.js
    Original file line number Diff line number Diff line change
    @@ -52,7 +52,6 @@ markUserTime = (function(l) {

    (function() {
    var wtt = function(g, n, t) {
    console.log(g + ': ' + n + ' = ' + t);
    if (window._trackTiming)
    _trackTiming(g, n, t);
    };
  10. @pmeenan pmeenan revised this gist Jul 7, 2013. 1 changed file with 38 additions and 3 deletions.
    41 changes: 38 additions & 3 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,42 @@ in the onload handler for any critical above-the-fold images.
    }());

    markUserTime = (function(l) {
    window.performance.mark(l);
    if (console && console.timeStamp)
    console.timeStamp(l);
    var raf = window.requestAnimationFrame ||
    (function(callback){setTimeout(callback, 0);});
    raf(function(){
    window.performance.mark(l);
    if (console && console.timeStamp)
    console.timeStamp(l);
    });
    });

    (function() {
    var wtt = function(g, n, t) {
    console.log(g + ': ' + n + ' = ' + t);
    if (window._trackTiming)
    _trackTiming(g, n, t);
    };
    utOnLoad = function() {
    var m = window.performance.getEntriesByType("mark");
    var lm={};
    for (i = 0; i < m.length; i++) {
    g = 'user';
    n = m[i].name;
    p = n.match(/([^\.]+)\.([^\.]*)/);
    if (p && p.length > 2) {
    g = p[1];
    n = p[2];
    }
    if (lm[g] == undefined || m[i].startTime > lm[g])
    lm[g] = m[i].startTime;
    wtt(g, n, m[i].startTime)
    }
    for (g in lm) {
    wtt('UserTimings', g, lm[g]);
    }
    };
    if (window.addEventListener)
    window.addEventListener('load', utOnLoad, false);
    else if (window.attachEvent)
    window.attachEvent('onload', utOnLoad);
    })();
  11. @pmeenan pmeenan revised this gist Jul 3, 2013. 1 changed file with 24 additions and 24 deletions.
    48 changes: 24 additions & 24 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -11,37 +11,37 @@ 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 object = typeof window != 'undefined' ? window : exports,
    var w = typeof window != 'undefined' ? window : exports,
    marks = [];
    object.performance || (object.performance = {});
    object.performance.now || (
    object.performance.now = performance.now || performance.webkitNow ||
    w.performance || (w.performance = {});
    w.performance.now || (
    w.performance.now = performance.now || performance.webkitNow ||
    performance.msNow || performance.mozNow);
    if (!object.performance.now){
    var start = Date.now ? Date.now() : +(new Date());
    if (!w.performance.now){
    var s = Date.now ? Date.now() : +(new Date());
    if (performance.timing && performance.timing)
    start = performance.timing.navigationStart
    object.performance.now = (function(){
    var nowOffset = Date.now ? Date.now() : +(new Date());
    return nowOffset - start;
    s = performance.timing.navigationStart
    w.performance.now = (function(){
    var n = Date.now ? Date.now() : +(new Date());
    return n-s;
    });
    }
    object.performance.mark || (
    object.performance.mark =
    object.performance.webkitMark ? object.performance.webkitMark :
    (function (label) {
    marks.push({'name':label,'entryType':'mark','startTime':object.performance.now(),'duration':0});
    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});
    }));
    object.performance.getEntriesByType || (
    object.performance.getEntriesByType =
    object.performance.webkitGetEntriesByType ? object.performance.webkitGetEntriesByType :
    (function (type) {
    return type == 'mark' ? marks : undefined;
    w.performance.getEntriesByType || (
    w.performance.getEntriesByType =
    w.performance.webkitGetEntriesByType ? w.performance.webkitGetEntriesByType :
    (function (t) {
    return t == 'mark' ? marks : undefined;
    }));
    }());

    markUserTime = function(label) {
    window.performance.mark(label);
    markUserTime = (function(l) {
    window.performance.mark(l);
    if (console && console.timeStamp)
    console.timeStamp(label);
    };
    console.timeStamp(l);
    });
  12. @pmeenan pmeenan revised this gist Jul 1, 2013. 1 changed file with 0 additions and 7 deletions.
    7 changes: 0 additions & 7 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -9,13 +9,6 @@ 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.
    (coming soon) WebPagetest will report on any user timing events that were recorded
    and also expose a high-level metric for when the last user timing event fired.
    With any luck we can also get RUM solutions to start reporting user timing events
    and we can significantly loosen our dependency on the (very broken) document
    onload times.
    */
    ;(function () {
    var object = typeof window != 'undefined' ? window : exports,
  13. @pmeenan pmeenan revised this gist Jul 1, 2013. 1 changed file with 19 additions and 0 deletions.
    19 changes: 19 additions & 0 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,22 @@
    /*
    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.
    (coming soon) WebPagetest will report on any user timing events that were recorded
    and also expose a high-level metric for when the last user timing event fired.
    With any luck we can also get RUM solutions to start reporting user timing events
    and we can significantly loosen our dependency on the (very broken) document
    onload times.
    */
    ;(function () {
    var object = typeof window != 'undefined' ? window : exports,
    marks = [];
  14. @pmeenan pmeenan created this gist Jul 1, 2013.
    35 changes: 35 additions & 0 deletions user-timing.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    ;(function () {
    var object = typeof window != 'undefined' ? window : exports,
    marks = [];
    object.performance || (object.performance = {});
    object.performance.now || (
    object.performance.now = performance.now || performance.webkitNow ||
    performance.msNow || performance.mozNow);
    if (!object.performance.now){
    var start = Date.now ? Date.now() : +(new Date());
    if (performance.timing && performance.timing)
    start = performance.timing.navigationStart
    object.performance.now = (function(){
    var nowOffset = Date.now ? Date.now() : +(new Date());
    return nowOffset - start;
    });
    }
    object.performance.mark || (
    object.performance.mark =
    object.performance.webkitMark ? object.performance.webkitMark :
    (function (label) {
    marks.push({'name':label,'entryType':'mark','startTime':object.performance.now(),'duration':0});
    }));
    object.performance.getEntriesByType || (
    object.performance.getEntriesByType =
    object.performance.webkitGetEntriesByType ? object.performance.webkitGetEntriesByType :
    (function (type) {
    return type == 'mark' ? marks : undefined;
    }));
    }());

    markUserTime = function(label) {
    window.performance.mark(label);
    if (console && console.timeStamp)
    console.timeStamp(label);
    };