我正在使用一个jquery插件来修复我生成的html表上的标题。不幸的是,插件的性能非常慢,我把它缩小到以下代码:
var $tbl = $(this);
var $tblhfixed = $tbl.find("thead");
$tblhfixed.find("th").each(function ()
$(this).css("width", $(this).width());
});
在一张有2,000行的桌子上大约需要40秒。有谁知道为什么它如此缓慢,更重要的是如何让它更快?我已经尝试了很多其他插件,这是唯一一个按照我想要的方式工作的插件。谢谢你的帮助
答案 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";
}