我有500多个运行客户端的JavaScript函数。我想测量客户端上每个函数的执行时间和相对频率,并将统计信息发送到服务器,以便找出首先需要优化的函数。
所有函数都是全局对象的一部分(如果它有帮助)。
如何进行自动测量?我需要一个全局函数来监视所有其他函数并测量它们。这可能吗?
答案 0 :(得分:2)
这样的事情应该可以解决问题(没有经过测试)
var profiler = (function(win){
var collector = {},
wrap = function(fn, name) {
var report = {calls: 0, times: []}; //create new report obj
collector[name] = report; //save it to collector
return function() {
var start, end, out;
report.calls++; //number of calls
start = performance.now();
out = fn.apply(this, arguments);
end = performance.now();
report.times.push(end - start); //time statistics
return out;
};
};
win.addEventListener('unload', function(){/*send collector here*/});
return function() {
[].forEach.call(arguments, function(holder, i) { //iterate over all namespaces
Object.keys(holder).forEach(function(key){ //iterate over every member
var fn = holder[key];
if(typeof fn === 'function') {
holder[key] = wrap(fn, i + '_' + key); //replace member
}
});
});
};
}(window));
用法
profiler(namespace1, namespace2 ...);
答案 1 :(得分:0)
这应该有效(click here for JSFiddle):
function testFunc(test) {
for(var i=0;i<100000000;i++) { i = i+test; }
};
function testFunc2(test) {
for(var i=0;i<100000000;i++) { i = i+test; }
};
var getPerfResults = (function(){
var timeRecords = {}, xTr = 0, name;
var setPerfRecords = function(oFn, fnIdentity) {
timeRecords[fnIdentity] = [];
return function(){
var xTime = performance.now();
var xResult = oFn.apply(this, arguments);
xTime = performance.now()-xTime;
timeRecords[fnIdentity].push(xTime);
return xResult;
};
};
for (name in window) {
try { window[name]; // Security exception may occur here
if (typeof window[name] === 'function')
window[name] = setPerfRecords(window[name], name);
}
catch(err) { }
}
return function() {
var resultObj = {}, n, i;
for(i in timeRecords) {
if(timeRecords.hasOwnProperty(i)
&& timeRecords[i].length > 0) {
resultObj[i] = 0;
for(n=0;n<timeRecords[i].length;n++) {
resultObj[i] = resultObj[i]+timeRecords[i][n];
}
resultObj[i] = resultObj[i]/timeRecords[i].length;
}
}
return resultObj;
};
}());
testFunc(1);
testFunc(10);
testFunc(100);
testFunc(1000);
testFunc(10000);
testFunc2(0);
document.body.innerHTML = JSON.stringify(getPerfResults());
答案 2 :(得分:0)
基于@Yury Tarabanko(我没有为我工作,但给了我一个灵感),这是我得到的:
//将存储性能重新存储的全局对象
perf = {};
然后,您需要一个包含所有其他功能并跟踪性能的函数。
//Function that actually tracks the perfomance, wrapping all other functions
function trackPerfomance() {
var name, fn;
for (name in jNTRender) { //jNTRender - is the namespace that I was analysing. Use yours or window
fn = jNTRender[name];
if (typeof fn === 'function') {
jNTRender[name] = (function(name, fn) {
var args = arguments;
return function() {
if (!perf[name]) perf[name] = {
timesCalled: 0,
timeTaken: 0,
averageTime: 0
}
var start = performance.now(),
out = fn.apply(this, arguments),
end = performance.now();
perf[name].timesCalled ++; //how many times function was called
perf[name].timeTaken += (end - start); //time taken for execution
perf[name].averageTime = perf[name].timeTaken/perf[name].timesCalled; //average execution time
return out;
}
})(name, fn);
}
}
}
你需要分析结果......
//Function that analyzes results - jQuery used for simplicity
function analyzePerfomance(){
functionsAverageTime = [];
$.each(jNTPerfomance, function(functionName, functionPerfomance){
functionsAverageTime.push([functionName, functionPerfomance.averageTime]);
});
functionsAverageTime.sort(function(a, b) { return b[1]-a[1] });
console.log('Slowest in average functions, msec');
$.each(functionsAverageTime, function(index, value){
console.log(index+1, value[0], value[1]);
});
functionsTimesCalled = [];
$.each(jNTPerfomance, function(functionName, functionPerfomance){
functionsTimesCalled.push([functionName, functionPerfomance.timesCalled]);
});
console.log('Most used functions, times');
$.each(functionsTimesCalled, function(index, value){
console.log(index+1, value[0], value[1]);
});
functionsTotalTimeSpent = [];
totalTime = 0;
$.each(jNTPerfomance, function(functionName, functionPerfomance){
totalTime += functionPerfomance.timeTaken;
});
$.each(jNTPerfomance, function(functionName, functionPerfomance){
functionsTotalTimeSpent.push([functionName, functionPerfomance.timeTaken, 100*functionPerfomance.timeTaken/totalTime]);
});
functionsTotalTimeSpent.sort(function(a, b) { return b[1]-a[1] });
console.log('Time taken by functions, msec, % of total time taken');
$.each(functionsTotalTimeSpent, function(index, value){
console.log(index+1, value[0], Math.round(value[1]), value[2].toFixed(2) + '%');
});
}
从控制台运行跟踪器。
trackPerfomance();
等待一段时间 - 分钟,小时...... 并分析性能:
analyzePerfomance();
以下是我在控制台中获得的内容。真的很有用,易于阅读。对于cource,可以通过ajax将 perf 对象发送到服务器。