利用jsPerf优化Web应用的性能

在前端开发的过程中,掌握好浏览器的特性进行有针对性的性能调优是一项基本工作,jsperf.com是一个用来发布基于HTML的针对性能比较的测试用例的网站,你可以在jsPerf上在线填写和运行测试用例,得到浏览器运行测试用例的性能,学会利用jsPerf会让你的优化工作事半功倍。

书写测试用例

我想写一个简单的例子,验证一个算法是否更高效,这里我想到了字符串的拼接。在JS里拼接大量字符串有两种常见的方法,一是直接用加号(+)连接所有的字符串,二是用数组的join函数拼接起来。在很多书中都提到采用第二种方法的效率更高,那么我们就用jsPerf来验证一下。

第一步,打开jsPerf(http://jsperf.com),在Test case details区域填入测试的基本信息,测试的名称(Title)、短名称(Slug),Slug用于生成将来的测试页面的地址,所以不能与现有的重复。然后你可以选择是否马上发布(Published),在Description区域填入测试的目的和方法之类的描述。

第二步就是写测试用例了。我准备为这两个算法各写一个测试用例(test case),而这两个例子都需要一个很大的字符串数组作为输入,这时你需要在Preparation code区域准备好这个数组,在"Define setup for all tests"区域填入如下代码,会为我生成这样一个大字符串数组。下面是生成数组的代码:

var bigArray = [];
for (var i = 0; i < 1000; i++) {
    bigArray.push('This is a test!test!test!');
}

你也可以在Define teardown for all tests区域执行一些JS代码,清除运行测试用例产生的DOM结点、JS变量等等,以免影响到再次运行测试用例。

除了准备JS代码之外,还可以在Preparation code HTML区域准备你的HTML代码、CSS样式表,以及引入第三方JS库(如jQuery等)。

准备好数组之后,就在下面的“Code snippets to compare”中分别填入算法的简单描述(Title)和代码(Code),Async选项框是用来测试一些异步调用的性能的,我们的代码没有使用异步方法,所以不必勾选。

直接用加号连接:

var result = '';
for (var i = 0, length = bigArray.length; i < length; i++) {
    result += bigArray[i];
}

用数组的join函数:

var result = bigArray.join('');

jsPerf默认只有两个测试用例,如果你要添加额外的,可以点击最下面的“Add code snippet”添加,另一个按钮“Beautify code”可以帮助你格式化代码,自动调整缩进,让代码显示更美观。

最后,点击“Save test case”保存测试用例。浏览器会自动跳转到测试页面。点击这里(http://jsperf.com/compare-string-concat)可以直接查看完整的测试用例。

有时在提交了测试用例之后发现有问题,可以通过在测试地址后面加/edit打开测试用例的编辑页面,添加和修改你的测试用例。

运行测试

好,点击“Run tests”按钮开始测试两种算法的性能。建议在运行性能测试之前,关闭无关的浏览器页面,关闭其他程序,退出不必要的后台进程,以保证结果不受其他环境的影响。你也可以通过点击个别测试用例的名字单独运行这个例子。

读懂测试结果

测试结果以每秒钟执行测试代码的次数(Ops/sec)显示,这个数值越大越好。除了这个结果外,同时会显示测试过程中的统计误差,以及相对最好的慢了多少(%),统计误差也是非常重要的指标,如果你写的测试用例不好,或者说后台正在运行一些其他程序,会造成统计误差过大,这时测试结果就不够可靠。

在我们这个例子中,在我的Chrome 24浏览器上,第二种方法比第一种方法慢了62%,在Firefox 18上,第二种方法慢了70%,我们惊奇地发现第二种方法反而比第一种更慢!只有在IE8上,第一种方法慢了78%。

jsPerf还会统计所有运行过这个测试用例的浏览器的比较结果,显示在下方的Browserscope区域,可以通过它直观地看出各个版本浏览器的性能横向和纵向比较情况。

异步测试

jsPerf也能支持像setTimeout这种异步的调用测试,异步测试用例需要在书写用例时选中“Async”,并且在异步调用结束后及时调用deffered.resolve()。这儿(http://jsperf.com/smallest-timeout)有一个异步测试用例的示例。

查看别人的测试用例

jsPerf上提供所有测试的查询,打开http://jsperf.com/browse就可以看到最近提交的测试,也可以输入关键词来进行查找。查看别人写的测试用例,可以帮助你发现更多性能调优的方法,以便用于自己的开发工作中。

For more complete information about compiler optimizations, see our Optimization Notice.