jQuery width()方法的性能
我是一个jquerynoob,试图找出我们在处理大型表时遇到的性能问题。我们有一个自制的表小部件,其中包括将列宽设置为标题宽度或行宽度的最大值 对于一个10行乘500列的表,这可能需要近40秒(!)的时间,考虑到该表可以在不到一秒钟的时间内呈现,这似乎是多余的 以下是整个功能:jQuery width()方法的性能,jquery,performance,Jquery,Performance,我是一个jquerynoob,试图找出我们在处理大型表时遇到的性能问题。我们有一个自制的表小部件,其中包括将列宽设置为标题宽度或行宽度的最大值 对于一个10行乘500列的表,这可能需要近40秒(!)的时间,考虑到该表可以在不到一秒钟的时间内呈现,这似乎是多余的 以下是整个功能: var dataTable = this._div.find('.data-table'); var headerTable = this._div.find('.data-header-table'); i
var dataTable = this._div.find('.data-table');
var headerTable = this._div.find('.data-header-table');
if (dataTable.length === 0 || headerTable.length === 0) {
return;
}
dataTable = dataTable[0];
headerTable = headerTable[0];
if (dataTable.rows.length === 0) {
return;
}
var dataTr = dataTable.rows[0];
var headerTr = headerTable.rows[headerTable.rows.length - 1];
var marginColumnWidths =
$(dataTr.cells[0]).outerWidth(true) +
$(dataTr.cells[1]).outerWidth(true) +
$(dataTr.cells[2]).outerWidth(true) -
DOM.getHPaddings($(headerTr.cells[0])) + 1;
$(headerTable)
.find('> tbody > tr > td:first-child')
.width('1%')
.children()
.first()
.width(marginColumnWidths);
for (var i = 1; i < headerTr.cells.length; i++) {
var headerTd = $(headerTr.cells[i]);
var dataTd = $(dataTr.cells[i + 2]);
var commonWidth = Math.max(
Math.min(headerTd.width(), 100),
dataTd.width()
);
headerTd.width('1%').find('> div').width(commonWidth);
dataTd.children().first().width(commonWidth);
}
恒定
var commonWidth = 100;
执行时间从38秒降至不到一秒,表明问题在于读取/计算当前宽度,而不是设置新宽度。从我所做的分析/采样来看,jQuery似乎花费了过多的时间来处理CSS计算
有人能推荐一种更有效的方法吗
编辑:
我尝试了css(“宽度”)和outerWidth(),但性能没有任何显著变化。我们使用的是jQuery 1.7.2,但升级到1.8.1并没有显著改变性能。使用.css(“width”)
而不是.width()
,对.width()
方法进行了更改,使其执行速度变慢。有关更多信息,请阅读以下内容:
据我所知-.width()
采用的是实际宽度(在css中并不总是一组),要获得它,浏览器必须计算它(强制页面重画和宽度计算本身)。现在,您正在设置宽度,浏览器需要重新绘制所有内容。它可能会稍微延迟,但在下一步中,您将再次测量宽度-浏览器必须重新绘制页面以获得真正的宽度。首先计算宽度,然后在另一个循环中设置计算值。我认为这应该有帮助
编辑:
将此方法与方法进行比较。差异不显著。看起来最好是使用css(“宽度”)时。以下是测试:
嗯,测试过了。与我建议的方法相比。看来差别不大。以下是测试: , , . 结果——几乎没有区别。最慢的“宽度一圈”。最快-使用
css
的一种。对我来说,有时不同
注意:四个不同的测试都是开案例的,因为js perf似乎没有清除测试案例之间的html状态
不确定在您的情况下可以做什么,但我看到奇怪的是.width('1%')
您正在使用。对我来说,你似乎不需要它,所以也许你可以尝试删除它 如果对非常大的表的表单元格(或标题)执行.width(以及.css(“width”)),则隐藏元素需要花费大量时间!!!,而且对于可见元素来说速度非常快。原因是,如果该元素是隐藏的,那么浏览器就很好,效率很高,如果该元素是可见的,那么浏览器就不会努力找出它的宽度。但是jQuery的.width,显然,对于隐藏元素,会返回宽度,如果它是可见的,而不是只返回零(它是隐藏的)。对于大型表,这意味着浏览器必须再次呈现整个表。如果桌子真的很大,它可能会占用一秒钟的时间。如果对多个隐藏列(仅测量其宽度)执行此操作,则页面将变得无用
所以不要测量隐藏元素的宽度,除非您确实需要知道
相关链接,重复我刚才说的(以及更多):誓言。那篇博文让人大开眼界。必须订阅这些提要。谢谢+1.嗯,测试过了。与我建议的方法相比。看来差别不大。以下是测试:。结果——几乎没有区别。最慢的宽度为一个循环。最快-使用
css
的一种。时而不同。注意:四个不同的测试都是基于案例的,因为js perf看起来没有清除测试案例之间的html状态。谢谢你的建议。我应该提到的是,我在jQuery1.7.2中尝试了css(“宽度”),但没有更快。我刚刚用1.8.1重新测试了一下,看看性能是否有所提高,但没有。
var commonWidth = 100;
var commonWidth = Math.max(
Math.min(parseFloat(headerTd.css("width")), 100),
dataTd.width()
);