为什么这个jquery这么慢?

时间:2011-03-03 11:06:30

标签: javascript jquery

我正在使用一个jquery插件来修复我生成的html表上的标题。不幸的是,插件的性能非常慢,我把它缩小到以下代码:

var $tbl = $(this);  
var $tblhfixed = $tbl.find("thead");  
$tblhfixed.find("th").each(function ()    
    $(this).css("width", $(this).width());  
});

在一张有2,000行的桌子上大约需要40秒。有谁知道为什么它如此缓慢,更重要的是如何让它更快?我已经尝试了很多其他插件,这是唯一一个按照我想要的方式工作的插件。谢谢你的帮助

5 个答案:

答案 0 :(得分:1)

罪魁祸首可能是.each

原因是当您使用.each而不是正常循环进行迭代时,您将为每次迭代调用一个函数。在这种情况下,函数调用具有相当大的开销,因为必须为每次迭代创建一个新的调用堆栈。

让它更快地改变

$tblhfixed.find("th").each(function ()    
    $(this).css("width", $(this).width());  
});

var elms = $tblhfixed.find("th");
for(var i=0, elm;elm = elms[i];i++) {
    elm.css("width", elm.width());  
}

答案 1 :(得分:1)

你不应该在传递给$(this)的函数内重复.each()。包装元素具有非平凡的开销,当你有20k元素时,这是不正确的。你希望在.each()调用中消除尽可能多的工作,或者完全消除它。

另外,为什么要查询find()两次,当你可以这样做时,这应该会给你相同的结果:

$ths = $('table thead th'); //or tableid, or something
$ths.css('width', $ths.width());

答案 2 :(得分:1)

我猜你遇到了我前段时间遇到的同样问题。它称之为“重新计算布局”或其他东西。

尝试将此脚本分成两个循环,如下所示:

var $tbl = $(this);
var $tblhfixed = $tbl.find("thead");
var widths = [];

// 1.
$tblhfixed.find("th").each(function ()
    widths.push($(this).width());
});

// 2.
$tblhfixed.find("th").each(function (index, element)
    $(this).css("width", widths[index]);
});

第一个将计算所有宽度。第二个将它们应用于TH的

<强> UPD: 您可以通过将此代码置于1.和2之间来提高性能。

$tblhfixed.hide();

并在2之后再次显示:

$tblhfixed.show();

答案 3 :(得分:1)

看起来$ .width()比原生get(0).clientWidth慢99倍,请查看此测试:http://jsperf.com/jq-width-vs-client-width

答案 4 :(得分:0)

首先,只有在需要传递所有嵌套节点时才应使用find()。在这里,您可以使用children()

其次,每次$(this)创建jQuery对象的新实例,而您可以创建一次:

var $this = $(this);

每次重新计算$(this).width()。确保您需要重新计算它。或者做:

var tableWidth = $this.width();

第三,根据@Martin Jespersen的说法,每次迭代都会创建function对象。

此外,您根本不需要jQuery。您可以直接访问DOM:

var tableWidth = ...; // get the table width the way you want
var thead = this.tHead;
var thRow = thead.rows[0];
for (var i = 0; i < thRow.length; ++i) {
  thRow.cells[i].style.width = tableWidth + "px";
}