我正在编写一个jQuery插件,我正处于优化阶段。
我想知道其中哪些会导致更快的脚本,以及哪种缓解因素很重要:
答案 0 :(得分:12)
浏览器的工作方式是在加载时创建一个内存中的DOM树,如下所示:
P
_______________|______________
| |
childNodes attributes
______________|___________ |
| | | title = 'Test paragraph'
'Sample of text ' DIV 'in your document'
|
childNodes
__________|_______
| | |
'HTML you might' B 'have'
因此,当您查找P > DIV > B
时,查找必须找到所有P
元素,然后查找P
中的所有DIV元素,然后查找DIV中的所有B
元素。嵌套越深,它需要执行的查找越多。此外,它可能会发现所有P > DIV
只发现它们都没有B
,并且会浪费时间查看所有P > DIV
个匹配项。
ID查找速度更快,因为ID保证是唯一的,因此DOM可以将它们存储为具有非常快速查找的哈希表条目。就jQuery而言,实现可能略有不同,但是,document.getElementById具有最快的查找时间,因此$('#my_node_id')
也应该非常快。
因此,如果您的节点没有ID,您可以找到最近的祖先,并找到相对于该祖先的节点
#my_node_id > div > b
因为查找只需要在#my_node_id
的子树下进行,它会比p > div > b
更快
答案 1 :(得分:11)
这个问题不够具体,所以我可以给你直接与你的代码相关的建议,但这里有一些我最喜欢的jQuery优化技巧:
#container
div中,请执行$(something, '#container');
.myclass
慢。在内部,jQuery必须通过每个元素来查看它是否具有您要搜索的类,至少对于那些不支持getElementsByClassName
的浏览器而言。如果您知道某个类只会应用于某个元素,那么{em>方式可以更快地执行tag.myclass
,因为jQuery可以使用本机getElementsByTagName
并仅搜索那些。$('#myform input:eq(2)');
或类似的事情,但我更愿意$('input','#myform').eq(2);
来帮助jQuery。答案 2 :(得分:5)
我认为你回答了自己的问题:'复杂的方式'是'它会破坏'的同义词 - 对html结构的任何更改都会破坏你的代码。
例如,假设您尝试获取myDiv
,并认为它是child
的最后一个兄弟:
<div>parent
<div>child</div>
<div>myDiv</div>
</div>
如果您稍后决定结构应该是这样的话,会发生什么?
<div>parent
<div>child</div>
<div>myDiv</div>
<div>child</div>
</div>
依靠关于结构的假设,你的代码变得非常脆弱。向节点添加类和ID将防止出现这种情况。
我认为你应该选择第一选择。还要记住,按类获取节点总是慢于通过id获取节点。
答案 3 :(得分:3)
使用我的插件,我尽可能地尝试限制我在文档中引入的钩子数量。 “钩子”我的意思是ID或类。
完全避免它们的最佳方法是保留对插件闭包中任何已创建元素的引用。例如:
jQuery.fn.addList = function(items, fn){
var $list = $('<ul/>').html('<li>' + items.join('</li><li>') + '</li>');
return this.each(function(){
$(this).append($list);
fn.call($list);
});
};
$('body').addList(['item 1', 'item 2'], function(){
var referenceToTheList = this;
console.log(referenceToTheList, '<- this is my list, no hooks involved!');
});
该列表可以围绕JavaScript函数(在多个地方引用和使用)进行,而不需要HTML中的任何钩子;从而使它尽可能不引人注目!
避免/限制挂钩在插件开发中尤其重要,因为你永远不知道它最终会被用在哪里。