CSS选择器性能,DOM解析

6

我的问题与DOM解析的触发相关,我想知道为什么使用CSS ID选择器比类选择器更快。DOM树什么时候需要重新解析,我应该使用什么技巧和性能增强来优化...还有,有人告诉我如果我这样做:

var $p = $("p");  
$p.css("color", "blue"); 
$p.text("Text changed!");

代替
$("p").css("color", "blue");  
$("p").text("Text changed!"); 

这是否适用于所有浏览器以提高性能?另外,我如何知道我的DOM树已被重新解析?


CSS选择器解析性能本身就足够微小。将jQuery对不同选择器(CSS或非CSS)进行不同解释的不同方式混合在一起只会使一切变得不必要地混乱。为这些细微差别而苦恼并不值得。 - BoltClock
http://www.artzstudio.com/2009/04/jquery-performance-rules/ 列出了许多jQuery性能提升的规则。 - rt2800
1
还要注意,您可以使用方法链。因此,您可以执行 $('p').css('').text('').morestuff() 以提高性能。 - mrtsherman
是的,我对链式编程唯一的顾虑就是有时候会迷失在链条中,而且调试起来更加困难,除非有不同的技巧?我想我必须要习惯它,这是 jQuery 处理许多事情的方式。 - Astronaut
3个回答

10

#id选择器比类选择器更快,因为: (a) 每个ID值只能有一个元素; (b) 浏览器可以维护一个映射表id -> element,所以#id选择器就能像进行单个映射查询一样快。

接下来,上面提出的第一个选项肯定更快,因为它避免了第二次查找,从而将基于选择器的总查找时间减少了2倍。

最后,您可以使用Chrome开发者工具中的选择器分析器(在Profiles面板中),来分析浏览器处理页面中选择器所花费的时间(匹配+应用样式到匹配的元素)。


嘿,不知道有选择器分析器。谢谢!+1 对我来说。 - mrtsherman
只有JavaScript选择器库才会将CSS ID选择器视为getElementById()调用,并检索具有匹配ID的第一个元素。严格来说,符合规范的CSS选择器引擎需要将所有具有给定ID的元素与该ID选择器匹配,即使有多个元素,因此如果浏览器保存了这样的映射,则不会与此特定匹配过程相关。但是,考虑到我们在谈论jQuery... - BoltClock
@BoltClock'saUnicorn: 我知道你喜欢规范 :), 所以 这个规范 指出 id 属性值必须在文档中是唯一的。如果有多个元素具有相同的 id 值,浏览器的行为将未定义(如果使用 document.getElementById() 更加如此)。 - Alexander Pavlov
@AlexanderPavlov:那是HTML,而不是CSS,这就解释了为什么DOM实现使用document.getElementById()。不错的判断。 - BoltClock
@Alexander Pavlov:根据这里的评论,那很有启发性,并且不会对CSS ID选择器在文档上产生影响。另请参见我最近在其他地方的答案。虽然我可能在这里发表了不必要的评论,但我们正在谈论jQuery/JS。只是一些额外的信息! - BoltClock
显示剩余5条评论

1

我鼓励你在有疑问时进行自己的性能测试。你可以在这里找到更多关于如何进行性能测试JavaScript代码的信息:如何对JavaScript代码进行性能测试?。一旦你自己测试了性能,你就不会忘记结果。

特别是在给定的jquery选择器上执行$()函数必须获取匹配的DOM节点。我不确定具体是如何工作的,但我猜测它是document.getElementById()document.getElementsByTagName()和其他方法的组合。这会产生一定的处理成本,无论它有多小,如果你只调用一次然后重复使用它,你可以节省一些处理时间。


1

ID选择器比类选择器更快,因为只有一个元素具有ID,但是许多元素可以共享一个类,并且必须进行搜索。

下面的代码不必要地解析了DOM两次,所以它肯定会更慢:

$("p").css("color", "blue");  
$("p").text("Text changed!"); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接