你如何测试JavaScript代码?

How do you performance test JavaScript code?

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

补充:除了只知道代码运行速度之外,是否有一种在JavaScript中测试性能的定量方法?


分析器绝对是获取数字的好方法,但根据我的经验,感知性能对用户/客户来说都很重要。例如,我们有一个带有Ext手风琴的项目,该手风琴扩展为显示一些数据,然后是一些嵌套的Ext网格。一切实际上都是渲染速度非常快,没有一次操作花费很长时间,只有很多信息一次全部渲染,所以对用户来说感觉很慢。

我们"修复"了这个,不是通过切换到更快的组件,或者优化某些方法,而是先渲染数据,然后使用setTimeout渲染网格。因此,首先出现信息,然后网格会在一秒钟后出现。总的来说,这样做需要稍微多一点的处理时间,但对于用户来说,感知性能得到了提升。

目前,Chrome分析器和其他工具普遍可用且易于使用,console.time()console.profile()performance.now()也是如此。 Chrome还为您提供了一个时间线视图,可以显示杀死您的帧速率,用户可能在哪里等待的内容等。

查找所有这些工具的文档非常简单,您不需要SO答案。 7年后,我仍然会重复我原来答案的建议,并指出你可以让代码慢速运行,用户不会注意到它,并且代码运行速度非常快,他们会抱怨相当快的代码不够快。或者您对服务器API的请求花了220毫秒。或者类似的东西。关键在于,如果你拿出一个分析器并去寻找工作,你会发现它,但它可能不是你的用户需要的工作。


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

你可以使用javascript计时器。但我通常使用原生Chrome(现在也在Firefox和Safari中)使用devTool方法console.time()& console.timeEnd()

我如何使用它的示例:

1
2
3
4
5
6
7
8
9
10
11
12
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

更新(2016年4月4日):

Chrome canary最近在开发工具源选项卡中添加了行级别概要文件,让您可以准确了解每行执行的时间长度!
enter image description here


我们总是可以通过简单的日期对象来测量任何函数所用的时间。

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


试试jsPerf。它是一个在线JavaScript性能工具,用于基准测试和比较代码片段。我用它所有的时间。


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

用法

1
2
3
4
5
var start = performance.now();

// code being timed...

var duration = performance.now() - start;

参考

  • https://developer.mozilla.org/en-US/docs/Web/API/Performance.now()
  • http://www.w3.org/TR/hr-time/#dom-performance-now


JSLitmus是一个用于创建临时JavaScript基准测试的轻量级工具

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

1
2
3
4
5
6
7
8
9
10
<script src="JSLitmus.js">


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++) {}  });
});

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

FireFox表现结果

FireFox Performance Result

IE性能结果

IE Performance Result


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

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

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


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

JavaScript速度测试

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


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


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


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

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


快速回答

在jQuery上(更具体地说是在Sizzle上),我们在你的浏览器上使用它(checkout master和open speed / index.html),而后者又使用了benchmark.js。这用于对库进行性能测试。

答案很长

如果读者不知道基准测试,工作负载和分析器之间的区别,请首先阅读spec.org"readme 1st"部分的一些性能测试基础。这是用于系统测试,但理解这个基础也将有助于JS perf测试。一些亮点:

What is a benchmark?

A benchmark is"a standard of measurement or evaluation" (Webster’s II Dictionary). A computer benchmark is typically a computer program that performs a strictly defined set of operations - a workload - and returns some form of result - a metric - describing how the tested computer performed. Computer benchmark metrics usually measure speed: how fast was the workload completed; or throughput: how many workload units per unit time were completed. Running the same computer benchmark on multiple computers allows a comparison to be made.

Should I benchmark my own application?

Ideally, the best comparison test for systems would be your own application with your own workload. Unfortunately, it is often impractical to get a wide base of reliable, repeatable and comparable measurements for different systems using your own application with your own workload. Problems might include generation of a good test case, confidentiality concerns, difficulty ensuring comparable conditions, time, money, or other constraints.

If not my own application, then what?

You may wish to consider using standardized benchmarks as a reference point. Ideally, a standardized benchmark will be portable, and may already have been run on the platforms that you are interested in. However, before you consider the results you need to be sure that you understand the correlation between your application/computing needs and what the benchmark is measuring. Are the benchmarks similar to the kinds of applications you run? Do the workloads have similar characteristics? Based on your answers to these questions, you can begin to see how the benchmark may approximate your reality.

Note: A standardized benchmark can serve as reference point. Nevertheless, when you are doing vendor or product selection, SPEC does not claim that any standardized benchmark can replace benchmarking your own actual application.

性能测试JS

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

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

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

如果某些事情表现非常糟糕,那么下一步就是寻找瓶颈。

我如何找到瓶颈?剖析

配置javascript执行的最佳方法是什么?


你可以在firebug中使用console.profile


我觉得执行时间是最好的衡量标准。


这是一个可重复使用的时间表。示例包含在代码中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
     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

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


UX Profiler从用户角度处理此问题。它将由某些用户操作(点击)引起的所有浏览器事件,网络活动等分组,并考虑延迟,超时等所有方面。


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

1
2
3
4
5
6
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);

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