JavaScript基准测试代码冻结了浏览器?

时间:2012-03-29 08:17:10

标签: javascript performance frameworks benchmarking

我正在构建一个用于对JavaScript框架代码性能进行基准测试的页面。这是页面http://qatrix.com/benchmark/set-css-style

之一

我的想法是使用独立的iframe独立运行代码,以便在没有冲突的情况下使用它。基准测试功能运行成功,能够返回合理的结果,但这个基准测试页面的一个大问题是,当代码运行时,它会暂时冻结 Web浏览器鼠标光标是指针它在哪里,一些鼠标悬停效果也无法使用。

那么,问题是什么?那怎么解决?我看到一些基准测试网站没有这个问题,但他们只是在同一页面下对代码进行基准测试,我认为这将与冲突有关。

以下是在iframe下运行基准测试的代码:

var benchmark_code = function ()
{
    <?php echo $_GET['code'] ?>
},
benchmark = function(times)
{
    var start = new Date(),
        i, end;
    for( i = 0; i < times; i++) 
    {
        if( i == 0 )
        {
            try {
                benchmark_code.call();
            }
            catch (e)
            {
                return e;
            }
        }
        else
        {
            benchmark_code.call();
        }
    }
    end = new Date(); 
    return end - start;
};

基准测试的源代码在这里(使用Qatrix框架):

http://qatrix.com/js/benchmark.js

1 个答案:

答案 0 :(得分:0)

Javascript与浏览器UI单线程。当javascript正在执行时,所有其他浏览器活动排队等待javascript线程完成。因此,在您的基准测试运行时,您将无法与该页面进行交互。

如果计算基准测试的每个循环并计算这些时间(而不是计算整个运行的时间),则可以通过使用setTimeout(fn, 0)运行每个循环来使浏览器保持活动状态。这将允许浏览器处理基准测试的每个循环之间的待处理事件。

这是一种异步运行这些测试的方法,因此浏览器可以在运行之间保持活动状态:

var benchmark = function(times, resultCallback) {
    var start, cum = 0, i = 0;

    function runOnce() {
         if (i++ < times) {
             start = new Date();
             benchmark_code.call();
             cum += new Date() - start;
             setTimeout(runOnce, 0);
         } else {
             resultCallback(cum);
         }
    }
    try {
        runOnce();
    } catch(e) {
        return e;
    }
};