我如何才能提高以下JQuery代码的性能:
var firstRowCellsWidth = new Array();
function initialize();
$('table.rgMasterTable > tbody > tr:first > td').each(function () {
firstRowCellsWidth.push({
normalCellWidth: $(this).width(),
firstTemplateCellWidth: $(this).find('table > tbody > tr > td:first').width()
});
});
}
我正在使用:first
,$(this)
,.find(, >
和each()
。这些显然会降低性能?
他们应该替换什么?或者它们的等效原生javascript代码是什么?
我猜测使用for循环而不是each()
方法。剩下的呢?
代码的目的: 计算表格每列的宽度。主表还有一个嵌套表,可以看出。
谢谢,
答案 0 :(得分:2)
var firstRowCellsWidth = [];
function initialize(){
var tables = document.getElementsByTagName("table");
for(var i=0; i<tables.length; i++){
if(/(^|\s)rgMasterTable(\s|$)/.test(tables[i].className)){
//a className is only valid if the className is contained within a space/nothing(^) and a space/nothing($)
var tcell = tables[i].rows[0].cells; //Any cell
for(var j=0; j<tcell.length; j++){
firstRowCellsWidth.push({
normalCellWidth:tcell[j].offsetWidth,
firstTemplateCellWidth:tcell[j].getElementsByTagName("td")[0].offsetWidth
//the first cell of any row of any table = the first occurence of a TD element
});
}
//break;
//Uncomment the previous line if you want to enumerate through all tables whose class equals .rgMasterTable
}
}
}
尽可能高效,不使用JQuery(懒惰的脚本编写者经常使用框架,他们不介意计算效率的损失)。
请注意,当文档结构与您的描述(tcell[j].getElementsByTagName("td"[0] is undefined
)不符时,将引发错误。
作为对maxedison(第三条评论)的回应,他质疑我的陈述,即JQuery的效率低于JavaScript。复制下面的代码段并将其粘贴到位置栏(本页)中。将出现一个提示,其中可以指定测试数量。测试运行后,会弹出一个警告,显示执行这些测试所需的毫秒数。提供了两个测试用例:
原生 JavaScript 测试用例:
javascript:alert((function(m){
for(var i=0, t=new Date; i<m; i++){
document.getElementsByTagName("table")[0].rows[0].cells[0];
}
return (new Date).getTime()-t.getTime();
})(prompt("Native\x20JS,\x20repeat\x20n\x20times:","10000")));
JQuery 测试用例。警告:不要从大量测试开始:
javascript:alert((function(m){
for(var i=0, t=new Date; i<m; i++){
$("table > tbody > tr > td:first");
}
return (new Date).getTime()-t.getTime();
})(prompt("JQuery,\20repeat\x20n\x20times","10")));
在我1岁的笔记本电脑上,使用FireFox 3.6.22,使用原生JavaScript的 10000 调用等于 5 JQuery执行。
答案 1 :(得分:1)
您实际遇到性能问题吗?看起来这种循环运行的次数并不多,每次迭代节省几毫秒会产生明显的差异。
无论如何,我意识到你可能是出于好奇而问,所以这是一种可以改善表现的方法:
$(this)
存储在变量中。请记住,$
实际上是一个函数,因此$(this)
表示您正在调用函数$
并将参数传递给它。作为一般经验法则,如果您需要多次使用$(this)
,将其存储在变量中会更快,因为它可以避免进行额外的$
函数调用。我也很想知道标准for
循环是否会明显快于.each()
。但是,当你问“它们的等效原生javascript代码是什么?”时,请注意你使用jQuery的全部原因是因为它更容易编写和使用jQuery。阅读,并且大多数“本机javascript”等价物将看起来&amp;要复杂得多。所以这个问题本身就会破坏使用jQuery的目的,除非你真的遇到了一些性能问题。
答案 2 :(得分:0)
一个改进是存储对您打算多次使用的任何jQuery对象的引用。
因此,不要多次使用$(this)
使用
var $this = $(this);
从现在开始使用$this
来引用该对象..
function initialize(){
$('table.rgMasterTable > tbody > tr:first > td').each(function () {
var $this = $(this);
firstRowCellsWidth.push({
normalCellWidth: $this.width(),
firstTemplateCellWidth: $this.find('table > tbody > tr > td:first').width()
});
});
}
答案 3 :(得分:0)
用原生循环替换.each可能不会做任何事情,.each只是做一个for循环。
你真的遇到了速度问题吗?
假设您将为表格提供静态布局,您可以找出如何使用.childNodes[]
向下导航。你会做类似
document.getElementById('myTable').childNodes[0].childNodes[0].childNodes[0]
。你可以想象,这很快就变得非常难看。
你可以通过删除> trbody >
部分来加快选择器的速度,除非你的trbody
中有一个表而trhead
中的另一个表没有做任何事情