Created
May 20, 2012 02:57
-
-
Save baado/2737233 to your computer and use it in GitHub Desktop.
Tracking JavaScript file loading time with Google Analytics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2012 Google Inc. All Rights Reserved. | |
/* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** | |
* @fileoverview A nice little script demo-ing how to use the _trackTiming | |
* feature in Google Analytics to track the time it takes to | |
* load resources asynchrounously. This script defines the TrackTiming | |
* class to abstract all the timing logic. You can reuse this class | |
* in your own code to simplify tracking. | |
* @author [email protected] (Nick Mihailovski) | |
*/ | |
/** | |
* The original source code is below. | |
* http://code.google.com/p/analytics-api-samples/source/browse/trunk/src/tracking/javascript/v5/user-timing/user-timing.js | |
* | |
* This source code is customized to use quickly, and added some options. | |
* But same to original, not work on IE 8 and below. | |
*/ | |
/** | |
* Settings * | |
* | |
* List your JavaScript files to "_loadJsAry" array. | |
* ['path/to/js/file', 'JavaScript Description'] | |
*/ | |
var _loadJsAry = [ | |
['js/ga.js', 'Load Google Analytics Component'] | |
, ['js/jquery-min.js', 'Load jQuery'] | |
, ['js/jquery-ui-min.js', 'Load jQuery'] | |
]; | |
/** | |
* If debug, up sample rate to 100%. If not debug, up sample rate to 1%. | |
* (google analytics default) | |
*/ | |
var debug = true; | |
var _ga = _ga || {}; | |
var _gaq = _gaq || []; | |
if (debug) { | |
_gaq.push(['_setSiteSpeedSampleRate', 100]); | |
} | |
var _curTrackIndex = 0; | |
/** | |
* Asynchronously loads a JavaScript resources by creating a DOM Script | |
* element and appending it to the page. The time it takes to load the | |
* script is tracking using a TrackTiming object. Just before the script | |
* element is added to the page, the TrackTiming timer is started. The | |
* entire TrackTiming object is then set as a property on the script | |
* object. And finally the script element is added to the DOM to force | |
* the browser to load the script resource. | |
* Added: version branch, relaying mechanism. | |
* @param {String} url The URL of a JavaScript resource to load | |
* asynchronously. | |
* @param {Function} callback The callback function to execute once the | |
* JavaScript resource has loaded. | |
* @param {Object} tt The TrackTiming object used to track the time the | |
* browser takes to load the resource. | |
*/ | |
function includeJS(debug) { | |
var url = cacheBust(_loadJsAry[_curTrackIndex][0]); | |
if ("undefined" !== typeof document.documentElement.style.maxHeight) { | |
if (!/*@cc_on!@*/false){ | |
var t1 = new TrackTiming('JavaScript Libraries', _loadJsAry[_curTrackIndex][1]); | |
if (debug) { | |
t1.debug(); | |
} | |
if ("undefined" !== typeof _loadJsAry[_curTrackIndex][2] && true == _loadJsAry[_curTrackIndex][2]) { | |
loadJs(url, utCallback, t1, true); | |
} | |
} else if (document.documentMode >= 9) { | |
// IE8 or below. | |
loadJsIE(url); | |
} else { | |
//IE7, IE8 (IE7 mode) | |
loadJsIE(url); | |
} | |
} else { | |
// IE 6.0 or below. | |
loadJsIE(url); | |
} | |
_curTrackIndex ++; | |
} | |
/** | |
* Asynchronously loads a JavaScript resources by creating a DOM Script | |
* element and appending it to the page. The time it takes to load the | |
* script is tracking using a TrackTiming object. Just before the script | |
* element is added to the page, the TrackTiming timer is started. The | |
* entire TrackTiming object is then set as a property on the script | |
* object. And finally the script element is added to the DOM to force | |
* the browser to load the script resource. | |
* Added: async paramater. | |
* @param {String} url The URL of a JavaScript resource to load | |
* asynchronously. | |
* @param {Function} callback The callback function to execute once the | |
* JavaScript resource has loaded. | |
* @param {Object} tt The TrackTiming object used to track the time the | |
* browser takes to load the resource. | |
* @param {?Boolean} async Whether JavaScript Library load asynchronously | |
* or not. default false. | |
*/ | |
function loadJs(url, callback, tt, async) { | |
var js = document.createElement('script'); | |
async = async || false; | |
js.async = async; | |
js.src = url; | |
js.onload = callback; | |
js.charset = 'UTF-8'; | |
var ss = document.getElementsByTagName('script'); | |
var s = ss[ss.length-1]; | |
js.time = tt.startTime(); | |
s.parentNode.insertBefore(js, s.nextSibling); | |
} | |
/** | |
* loadJs() for IE 8 or below. | |
* But still this version do not work correctly. | |
*/ | |
function loadJsIE(url) { | |
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); | |
xmlHttp.onreadystatechange = function() { | |
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){ | |
utCallbackIE(xmlHttp); | |
} | |
}; | |
xmlHttp.open("GET", url, true); | |
xmlHttp.send(null); | |
} | |
/** | |
* Callback function after one JavaScript loaded. This will be executed once the JavaScript | |
* resource is loaded from loadJs. The event object is the onload event | |
* fired from the script element. So the event object is used to get a | |
* reference to the script object as well as the TrackTiming object. Finally | |
* the elapsed time is outputed to the page. | |
* Add: relaying mechanism. if next JavaScript exists, load it. | |
* @param {Object} event The onload event object that is fired once the | |
* script has loaded. | |
*/ | |
function utCallback(event) { | |
var e = event || window.event; | |
var target = e.target ? e.target : e.srcElement; | |
target.time.endTime().send(); | |
if (typeof(_loadJsAry[_curTrackIndex]) !== 'undefined') { | |
includeJS(debug); | |
} | |
} | |
function utCallbackIE(xmlHttp) { | |
var url; | |
eval(xmlHttp.responseText); | |
if (typeof(_loadJsAry[_curTrackIndex]) !== 'undefined') { | |
includeJS(debug); | |
} | |
} | |
/** | |
* Utility function to add a random number as a query parameter to the url. | |
* This assumes the URL doesn't have any existing query parameters or | |
* anchor tags. | |
* @param {String} url The url to add cache busting to. | |
*/ | |
function cacheBust(url) { | |
if (url.indexOf('?') >= 0) { | |
return url + '&t=' + Math.round(Math.random() * 100000); | |
} else { | |
return url + '?t=' + Math.round(Math.random() * 100000); | |
} | |
} | |
function TrackTiming(category, variable, opt_label) { | |
/** | |
* Maximum time that can elapse for the tracker to send data to Google | |
* Analytics. Set to 10 minutes in milliseconds. | |
* @type {Number} | |
*/ | |
this.MAX_TIME = 10 * 60 * 1000; | |
this.category = category; | |
this.variable = variable; | |
this.label = opt_label ? opt_label : undefined; | |
this.startTime; | |
this.elapsedTime; | |
this.isDebug = false; | |
return this; | |
} | |
/** | |
* Starts the timer. | |
* @return {Object} This TrackTiming instance. Useful for chaining. | |
*/ | |
TrackTiming.prototype.startTime = function() { | |
this.startTime = new Date().getTime(); | |
return this; | |
}; | |
/** | |
* Ends the timer and sets the elapsed time. | |
* @return {Object} This TrackTiming instance. Useful for chaining. | |
*/ | |
TrackTiming.prototype.endTime = function() { | |
this.elapsedTime = new Date().getTime() - this.startTime; | |
return this; | |
}; | |
/** | |
* Enables or disables the debug option. When set, this will override the | |
* default sample rate to 100% and output each request to the console. | |
* When set to false, will send the default sample rate configured by | |
* calling the _setSampleRate tracking method. | |
* @param {?Boolean} opt_enable Enables or disables debug mode. If not present, | |
* debug mode will be enabled. | |
* @return {Object} This TrackTiming instance. Useful for chaining. | |
*/ | |
TrackTiming.prototype.debug = function(opt_enable) { | |
this.isDebug = opt_enable == undefined ? true : opt_enable; | |
return this; | |
}; | |
/** | |
* Send data to Google Analytics with the configured variable, action, | |
* elapsed time and label. This function performs a check to ensure that | |
* the elapsed time is greater than 0 and less than MAX_TIME. This check | |
* ensures no bad data is sent if the browser client time is off. If | |
* debug has been enebled, then the sample rate is overridden to 100% | |
* and all the tracking parameters are outputted to the console. | |
* @return {Object} This TrackTiming instance. Useful for chaining. | |
*/ | |
TrackTiming.prototype.send = function() { | |
if (0 < this.elapsedTime && this.elapsedTime < this.MAX_TIME) { | |
var command = ['_trackTiming', this.category, this.variable, | |
this.elapsedTime, this.label]; | |
if (this.isDebug) { | |
// Override sample rate if debug is enabled. | |
command.push(100); | |
if (window.console && window.console.log) { | |
console.log(command); | |
} | |
} | |
_gaq.push(command); | |
} | |
return this; | |
}; | |
includeJS(debug); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment