# 開發背景 - 短時間內完成網頁性能統計上傳,考慮到企業內實際環境,很多網頁/系統需要運行在IE 5 相容模式下,開發一個腳本,在不影響原網頁的情況下,收集相應 用戶電腦 打開網頁的性能指標。 # 收集要素 - 進入頁面時間,載入Js時間 - 頁面所有元素載入完成時間 - 因為在原網頁將該腳本放到 ...
開發背景
- 短時間內完成網頁性能統計上傳,考慮到企業內實際環境,很多網頁/系統需要運行在IE 5 相容模式下,開發一個腳本,在不影響原網頁的情況下,收集相應 用戶電腦 打開網頁的性能指標。
收集要素
- 進入頁面時間,載入Js時間
- 頁面所有元素載入完成時間
- 因為在原網頁將該腳本放到最前面,故兩者時間差為用戶實際等待頁面Ready時間(白屏),實際體驗可能與渲染引擎相關(現代瀏覽器 大大快於IE,故該指標可作參考)
- IE 打開頁面預設彈窗,會影響結束時間,會以用戶點擊彈窗作為結束
- 瀏覽器信息等可自行拓展
# 使用方法
- 引入代碼文件,並給特定`id`, 相應標簽屬性可追加自定義值,用於輔助統計
- 涉及js 回調,所以需要提前賦值
# 技術特點
- 瀏覽器相容(主要是IE 5、低侵入)
- 無三方庫,考慮方便快速拓展
(function () {
Date.prototype.pattern = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小時
"H+": this.getHours(), //小時
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
var week = {
"0": "/u65e5",
"1": "/u4e00",
"2": "/u4e8c",
"3": "/u4e09",
"4": "/u56db",
"5": "/u4e94",
"6": "/u516d"
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
if (/(E+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
function getJsScriptDataScript() {
var data = document.getElementById('statisticalScriptId').getAttribute('data');
var key = 'code';
if (data) {
var result = data.match(new RegExp(key + "=[^\?\&]+", "g"));
var value = result ? result[0].split('=')[1] : '';
return value;
}
return '';
}
function getJsScriptRemark() {
return document.getElementById('statisticalScriptId').src;
}
//相容bind函數
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var _this = this;
var obj = arguments[0];
var ags = Array.prototype.slice.call(arguments, 1);
return function () {
_this.apply(obj, ags);
};
};
}
//相容addEventListener函數
function addEventListener(ele, event, fn) {
if (ele.addEventListener) {
ele.addEventListener(event, fn, false);
} else {
ele.attachEvent('on' + event, fn.bind(ele));
}
}
//相容removeEventListener函數
function removeEventListener(ele, event, fn) {
if (ele.removeEventListener) {
ele.removeEventListener(event, fn, false);
} else {
ele.detachEvent('on' + event, fn.bind(ele));
}
}
//閉包自治性
var ClientInfo = {
InJsTime: '',
InteractiveTime: '',
DOMContentLoadedTime:'',
LoadTime: '',
ComputeName: '',
UserName: '',
IdentifyCode: getJsScriptDataScript(),
Remark: getJsScriptRemark(),
Href: '',
Origin: '',
Host: '',
Port: '',
PathName:''
};
ClientInfo.InJsTime = getNowDateTime();
try {
var WshShell = new ActiveXObject("WScript.Shell");
//document.write("電腦名 = " + WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") + "<br/>");
//document.write("登錄用戶名 = " + WshShell.ExpandEnvironmentStrings("%USERNAME%") + "<br/>");
ClientInfo.ComputeName = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%");
ClientInfo.UserName = WshShell.ExpandEnvironmentStrings("%USERNAME%");
} catch (e) {
}
addEventListener(window, 'load', function () {
//console.log('window load ' + (new Date()).pattern("yyyy-MM-dd hh:mm:ss S"));
ClientInfo.LoadTime = getNowDateTime();
sendData();
});
addEventListener(document, 'readystatechange', function () {
var state = document.readyState;
if (state == 'interactive') {
ClientInfo.InteractiveTime = getNowDateTime();
//console.log('document ' + document.readyState + (new Date()).pattern("yyyy-MM-dd hh:mm:ss S"));
}
});
addEventListener(document, 'DOMContentLoaded', function () {
ClientInfo.DOMContentLoadedTime = getNowDateTime();
//console.log('document DOMContentLoaded' + (new Date()).pattern("yyyy-MM-dd hh:mm:ss S"));
});
function getNowDateTime() {
var timeOffSet = (new Date()).getTimezoneOffset();
return (new Date()).getTime() - timeOffSet * 60 * 1000; //(new Date()).pattern("yyyy-MM-dd hh:mm:ss S");
}
function sendData() {
ClientInfo.Href = window.location.href;
ClientInfo.Origin = window.location.origin;
ClientInfo.Host = (window.location.host).toLowerCase().replace(/.chn.nexchip/, "");
ClientInfo.Port = window.location.port;
ClientInfo.PathName = window.location.pathname;
var hostArray = 'xxxt01,xxxs01,xxxs02';
var url = '';
if (borGHostArray.indexOf(ClientInfo.Host) > -1) {
url = window.location.protocol + "//" + window.location.host + "/bridgeapi/Api/BridgePageRecord/PostData"
} else {
url = 'http://xxxs01x/msgcenterapi/Api/SeriPageLoadRecord/PostData';
}
var paramObj = {
httpUrl:url,
type: 'post',
data: ClientInfo
}
/*請求調用*/
httpRequest(paramObj, function (respondDada) {
//這裡編寫成功的回調函數
//console.log(respondDada)
}, function () {
//console.log('網路錯誤');
});
}
function httpRequest(paramObj, fun, errFun) {
var xmlhttp = null;
/*創建XMLHttpRequest對象,
*老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 對象:new ActiveXObject("Microsoft.XMLHTTP")
* */
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
/*判斷是否支持請求*/
if (xmlhttp == null) {
alert('你的瀏覽器不支持XMLHttp');
return;
}
/*請求方式,並且轉換為大寫*/
var httpType = (paramObj.type || 'GET').toUpperCase();
/*數據類型*/
var dataType = paramObj.dataType || 'json';
/*請求介面*/
var httpUrl = paramObj.httpUrl || '';
/*是否非同步請求*/
var async = paramObj.async || true;
/*請求參數--post請求參數格式為:foo=bar&lorem=ipsum*/
var paramData = paramObj.data || [];
var requestData = '';
for (var name in paramData) {
requestData += name + '=' + paramData[name] + '&';
}
requestData = requestData == '' ? '' : requestData.substring(0, requestData.length - 1);
//console.log(requestData)
/*請求接收*/
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
/*成功回調函數*/
fun(xmlhttp.responseText);
} else {
/*失敗回調函數*/
errFun;
}
}
/*介面連接,先判斷連接類型是post還是get*/
if (httpType == 'GET') {
xmlhttp.open("GET", httpUrl, async);
xmlhttp.send(null);
} else if (httpType == 'POST') {
xmlhttp.open("POST", httpUrl, async);
//發送合適的請求頭信息
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(requestData);
}
}
//setTimeout(function () { alert('表單打開超過20分鐘,請先暫存或刷新,否則可能會丟失數據') }, 1000 * 60 * 20);
})();
在未知中徜徉,
求心之蕩漾。