如何对JavaScript代码进行性能测试?

CPU周期,内存使用情况,执行时间等等?

除了感知代码的运行速度之外,是否有一种量化的方法来测试JavaScript的性能?

256562 次浏览

黄金法则是在任何情况下都不要锁定用户的浏览器。在此之后,我通常会查看执行时间,然后是内存使用情况(除非您正在做一些疯狂的事情,在这种情况下,内存使用的优先级可能更高)。

我发现执行时间是最好的衡量标准。

你可以使用这个:http://getfirebug.com/js.html。它有一个JavaScript分析器。

有些人建议使用特定的插件和/或浏览器。我不会,因为他们只真的有用的一个平台;在Firefox上的测试运行不能准确地转换到IE7上。考虑到99.999999%的网站有多个浏览器访问他们,您需要检查所有流行平台上的性能。

我的建议是将其保留在JS中。创建一个包含所有JS测试的基准测试页面,并计时执行。您甚至可以使用ajax将结果发送给您,以保持它完全自动化。

然后在不同的平台上重复。

剖析器绝对是获取数据的好方法,但根据我的经验,对用户/客户来说,感知性能才是最重要的。例如,我们有一个带有Ext手风琴的项目,它展开来显示一些数据,然后显示一些嵌套的Ext网格。所有内容都呈现得非常快,没有一个操作需要很长时间,只是有很多信息同时呈现,所以用户感觉很慢。

我们“修复”了这个问题,不是通过切换到一个更快的组件,或优化一些方法,而是通过先呈现数据,然后用setTimeout呈现网格。所以,信息先出现,然后网格会在一秒钟后出现。总的来说,这样做需要稍微多一点的处理时间,但对于用户来说,感知性能得到了改善。


现在,Chrome分析器和其他工具普遍可用,易于使用,就像
一样 console.time() (mozilla-docschrome-docs)
console.profile() (mozilla-docschrome-docs)
performance.now() (mozilla-docs)
Chrome也给你一个时间轴视图,可以告诉你什么是杀死你的帧率,用户可能在哪里等待,等等

找到所有这些工具的文档真的很容易,你不需要一个SO答案。7年后,我仍然会重复我最初回答的建议,并指出你可以让慢代码一直运行,而用户不会注意到它,而非常快的代码在他们注意到的地方运行,他们会抱怨非常快的代码不够快。或者您对服务器API的请求花费了220ms。或者其他类似的东西。重点仍然是,如果你使用分析器去寻找工作,你会找到它,但它可能不是你的用户需要的工作。

我认为JavaScript性能(时间)测试已经足够了。我找到了一篇关于JavaScript性能测试的非常方便的文章。

我通常只测试javascript的性能,脚本运行多长时间。jQuery Lover提供了一个很好的测试javascript代码性能的文章链接,但这篇文章只展示了如何测试javascript代码运行多长时间。我还建议阅读一篇文章,叫做“在处理巨大数据集时改进jQuery代码的5个技巧”。

我们总是可以通过简单的date对象测量任何函数所花费的时间

var start = +new Date();  // log start timestamp
function1();
var end =  +new Date();  // log end timestamp
var diff = end - start;

JSLitmus是一个轻量级的工具,用于创建特别的JavaScript基准测试

让我们检查function expressionfunction constructor之间的性能:

<script src="JSLitmus.js"></script>
<script>


JSLitmus.test("new Function ... ", function() {
return new Function("for(var i=0; i<100; i++) {}");
});


JSLitmus.test("function() ...", function() {
return (function() { for(var i=0; i<100; i++) {}  });
});


</script>

我上面所做的是创建一个执行相同操作的function expressionfunction constructor。结果如下:

FireFox性能结果

FireFox性能结果

IE性能结果

IE性能结果

jsPerf试试。这是一个在线javascript性能测试工具,用于对代码段进行基准测试和比较。我一直在用它。

下面是一个简单的函数,显示传入函数的执行时间:

var perf = function(testName, fn) {
var startTime = new Date().getTime();
fn();
var endTime = new Date().getTime();
console.log(testName + ": " + (endTime - startTime) + "ms");
}

你可以在firebug中使用console.profile

我同意,感知到的表现真的是最重要的。但有时我只是想知道哪种方法做某事更快。有时这种差异是巨大的,值得了解。

你可以使用javascript计时器。但我通常会得到更一致的结果使用本机Chrome(现在也在Firefox和Safari) devTool方法console.time() &console.timeEnd()

我如何使用它的例子:

var iterations = 1000000;
console.time('Function #1');
for(var i = 0; i < iterations; i++ ){
functionOne();
};
console.timeEnd('Function #1')


console.time('Function #2');
for(var i = 0; i < iterations; i++ ){
functionTwo();
};
console.timeEnd('Function #2')

Results Look like this

更新(4/4/2016):

Chrome金丝雀最近添加了线级剖析开发工具源代码选项卡,让你看到每一行执行了多长时间! enter image description here < / p >

这是为特定操作收集性能信息的好方法。

start = new Date().getTime();
for (var n = 0; n < maxCount; n++) {
/* perform the operation to be measured *//
}
elapsed = new Date().getTime() - start;
assert(true,"Measured time: " + elapsed);

迅速的回答

在jQuery上(更具体地说在Sizzle上),我们使用(在浏览器上签出master和打开speed/index.html),它反过来使用benchmark.js。这用于对库进行性能测试。

长回答

如果读者不知道基准测试、工作负载和分析器之间的区别,首先阅读spec.org的“readme 1st”部分上的一些性能测试基础。这是针对系统测试的,但是理解这个基础也会有助于JS的性能测试。以下是一些最突出的结果:

什么是基准?

基准是“衡量或评价的标准”(韦氏词典)。计算机基准测试通常是一个计算机程序,它执行一组严格定义的操作(工作负载),并返回某种形式的结果(度量),描述被测试计算机的执行情况。计算机基准度量通常度量速度:工作负载完成的速度有多快;或吞吐量:单位时间内完成多少个工作负载单元。在多台计算机上运行相同的计算机基准测试可以进行比较。

我应该对自己的应用程序进行基准测试吗?

理想情况下,最好的系统比较测试是您自己的应用程序和您自己的工作负载。不幸的是,使用您自己的应用程序和您自己的工作负载,为不同的系统获得广泛的可靠、可重复和可比较的测量通常是不切实际的。问题可能包括生成好的测试用例、机密性问题、难以确保可比条件、时间、金钱或其他约束。

如果不是我自己的应用程序,那是什么?

您可能希望考虑使用标准化基准作为参考点。理想情况下,标准化基准测试应该是可移植的,并且可能已经在您感兴趣的平台上运行过了。但是,在考虑结果之前,您需要确保了解应用程序/计算需求与基准测试所测量的内容之间的相关性。基准测试与您运行的应用程序类型相似吗?工作负载是否具有类似的特征?根据您对这些问题的回答,您可以开始了解基准测试是如何接近您的实际情况的。

注意:标准化基准可以作为参考点。然而,当您在选择供应商或产品时,SPEC并没有声称任何标准化的基准测试可以取代您自己的实际应用程序的基准测试。

性能测试JS

理想情况下,最好的性能测试是使用自己的应用程序和自己的工作负载来切换需要测试的内容:不同的库、机器等。

如果这是不可行的(通常是不可行的)。重要的第一步:定义您的工作量。它应该反映应用程序的工作负载。在这个演讲中,Vyacheslav Egorov谈到了你应该避免的糟糕工作负载。

然后,你可以使用benchmark.js这样的工具来帮助你收集指标,通常是速度或吞吐量。在Sizzle上,我们感兴趣的是比较修复或更改如何影响库的系统性能。

如果某些东西执行得非常糟糕,那么下一步就是寻找瓶颈。

如何找到瓶颈?分析器

分析javascript执行情况的最佳方法是什么?< / >

大多数浏览器现在都在performance.now()中实现了高分辨率计时。在性能测试方面,它优于new Date(),因为它独立于系统时钟运行。

使用

var start = performance.now();


// code being timed...


var duration = performance.now() - start;

参考文献

  • < a href = " https://developer.mozilla.org/en-US/docs/Web/API/Performance.now () " > https://developer.mozilla.org/en-US/docs/Web/API/Performance.now () < / >
  • < a href = " http://www.w3.org/TR/hr-time/ dom-performance-now " > http://www.w3.org/TR/hr-time/ dom-performance-now < / >

我有一个小工具,可以在浏览器中快速运行小的测试用例,并立即得到结果:

JavaScript速度测试

您可以在测试过的浏览器中测试代码并找出哪种技术更好。

用户体验分析器从用户的角度来解决这个问题。它将所有浏览器事件、网络活动等由用户操作(点击)引起的事件进行分组,并考虑到延迟、超时等所有方面。

下面是一个用于时间性能的可重用类。示例包含在代码中:

/*
Help track time lapse - tells you the time difference between each "check()" and since the "start()"


*/
var TimeCapture = function () {
var start = new Date().getTime();
var last = start;
var now = start;
this.start = function () {
start = new Date().getTime();
};
this.check = function (message) {
now = (new Date().getTime());
console.log(message, 'START:', now - start, 'LAST:', now - last);
last = now;
};
};


//Example:
var time = new TimeCapture();
//begin tracking time
time.start();
//...do stuff
time.check('say something here')//look at your console for output
//..do more stuff
time.check('say something else')//look at your console for output
//..do more stuff
time.check('say something else one more time')//look at your console for output

我也在找类似的东西,但发现了这个。

< a href = " https://jsbench。我/ noreferrer“rel = > https://jsbench.me/ < / >

它允许两边比较,然后你也可以分享结果。

性能测试最近成了一个流行词,但这并不是说性能测试在QA中不是一个重要的过程,甚至在产品发布之后也不是。当我开发应用程序时,我使用了许多不同的工具,其中一些上面提到过,比如chrome分析器,我通常会看一个SaaS或一些开源的东西,我可以开始并忘记它,直到我得到警告,说有些东西出了问题。

有很多很棒的工具可以帮助您关注性能,而不需要您跳过一些基本的提醒设置。这里有一些我认为值得你自己去看看。

  1. Sematext.com
  2. Datadog.com
  3. Uptime.com
  4. Smartbear.com
  5. Solarwinds.com

为了画出更清晰的画面,在这里是一个关于如何为react应用程序设置监控的小教程。

你可以使用https://github.com/anywhichway/benchtest,它用性能测试包装现有的Mocha单元测试。

性能。mark (Chrome 87 ^)

performance.mark('initSelect - start');
initSelect();
performance.mark('initSelect - end');

enter image description here

这是一个非常老的问题,但我认为我们可以提供一个基于es6的简单解决方案来快速测试你的代码。

这是执行时间的一个基本工作台。我们使用performance.now()来提高精度:

/**
* Figure out how long it takes for a method to execute.
*
* @param {Function} method to test
* @param {number} iterations number of executions.
* @param {Array} list of set of args to pass in.
* @param {T} context the context to call the method in.
* @return {number} the time it took, in milliseconds to execute.
*/
const bench = (method, list, iterations, context) => {
let start = 0
const timer = action => {
const time = performance.now()
switch (action) {
case 'start':
start = time
return 0
case 'stop':
const elapsed = time - start
start = 0
return elapsed
default:
return time - start
}
};


const result = []
timer('start')
list = [...list]
for (let i = 0; i < iterations; i++) {
for (const args of list) {
result.push(method.apply(context, args))
}
}
const elapsed = timer('stop')
    

console.log(`Called method [${method.name}]
Mean: ${elapsed / iterations}
Exec. time: ${elapsed}`)




return elapsed
}


const fnc = () => {}
const isFunction = (f) => f && f instanceof Function
const isFunctionFaster = (f) => f && 'function' === typeof f




class A {}


function basicFnc(){}
async function asyncFnc(){}


const arrowFnc = ()=> {}
const arrowRFnc = ()=> 1


// Not functions
const obj = {}
const arr = []
const str = 'function'
const bol = true
const num = 1
const a = new A()


const list = [
[isFunction],
[basicFnc],
[arrowFnc],
[arrowRFnc],
[asyncFnc],
[Array],
[Date],
[Object],
[Number],
[String],
[Symbol],
[A],
[obj],
[arr],
[str],
[bol],
[num],
[a],
[null],
[undefined],
]




const e1 = bench(isFunction, list, 10000)
const e2 = bench(isFunctionFaster, list, 10000)


const rate = e2/e1
const percent = Math.abs(1 - rate)*100


console.log(`[isFunctionFaster] is ${(percent).toFixed(2)}% ${rate < 1 ? 'faster' : 'slower'} than [isFunction]`)