改善jQuery选择器性能的好方法?

时间:2008-09-05 16:22:27

标签: javascript jquery performance css-selectors

我正在寻找能够改善jQuery调用的选择器性能的任何方法。特别是这样的事情:

$("div.myclass")$(".myclass")

更快

我认为可能是这样,但我不知道jQuery是否足够聪明,可以先按标签名称限制搜索等等。任何人对如何制定jQuery选择器字符串以获得最佳性能有什么想法?

12 个答案:

答案 0 :(得分:36)

毫无疑问,首先按标记名称进行过滤比按类名过滤要快得多

在所有浏览器本地实现getElementsByClassName之前都会出现这种情况,就像getElementsByTagName一样。

答案 1 :(得分:14)

在某些情况下,您可以通过限制其上下文来加快查询速度。如果您有元素引用,则可以将其作为第二个参数传递以限制查询的范围:

$(".myclass", a_DOM_element);

应该比

更快
$(".myclass");

如果你已经有一个_DOM_element并且它明显小于整个文档。

答案 2 :(得分:5)

为了完全理解什么是更快,你必须了解CSS解析器的工作原理。

您传入的选择器使用RegExp拆分为可识别的部分,然后逐个处理。

一些选择器如ID和TagName,使用浏览器的本机实现更快。而其他类似于类和属性的程序是分开编程的,因此要慢得多,需要循环选择元素并检查每个类名。

是的,回答你的问题:

$('tag.class')比$('。class')更快。为什么? 在第一种情况下,jQuery使用本机浏览器实现将选择过滤到您需要的元素。只有这样,它才会启动较慢的.class实现过滤到您要求的内容。

在第二种情况下,jQuery使用它的方法通过抓取类来过滤每个元素。

这比jQuery传播得更远,因为所有的javascript库都基于此。唯一的另一个选择是使用xPath,但目前在所有浏览器中都没有得到很好的支持。

答案 3 :(得分:5)

正如Reid所说,jQuery是自下而上的。虽然

  

这意味着$('#foo bar div')是一个   慢于$('bar div #foo')

这不是重点。如果您有#foo,那么无论如何都不会在选择器中放置任何内容,因为ID必须是唯一的。

重点是:

  • 如果您从带有ID的元素中选择任何内容,请先选择后者,然后使用.find.children等:$('#foo').find('div')
  • 选择器的最左边(第一个)部分可以缩放到应该最有效的最右边(最后)部分,这意味着如果你不这样做有一个ID,请确保您正在寻找$('div.common[slow*=Search] input.rare')而不是$('div.rare input.common[name*=slowSearch]') - 因为这并不总是适用,请确保通过相应的拆分来强制选择顺序。

答案 4 :(得分:4)

以下是如何提高jQuery选择器的性能:

答案 5 :(得分:3)

我将添加一个注释,在99%的网络应用程序中,即使是ajax繁重的应用程序,Web服务器的连接速度和响应也将推动应用程序的性能而不是javascript。我并不是说你应该故意编写慢速代码,或者通常意识到哪些东西可能比其他代码更快。

但我想知道你是否正在尝试解决一个尚未存在的问题,或者即使你正在优化某些可能在不久的将来更改的事情(例如,如果有更多人开始使用支持前面提到的getElementsByClassName()功能的浏览器,那么优化后的代码实际运行得更慢。

答案 6 :(得分:3)

另一个寻找性能信息的地方是Hugo Vidal Teixeira的选择器性能分析页面。

http://www.componenthouse.com/article-19

通过id,逐个选择器和选择器前缀标记名称,可以很好地降低选择器的速度。

id最快的选择器是:$(“#id”)

班级中最快的选择器是:$('tag.class')

因此,按标签添加前缀仅在按类选择时有帮助!

答案 7 :(得分:0)

我参与了一些jQuery邮件列表,从我在那里读到的,他们很可能按标签名称和类名称进行过滤(反之亦然,如果它更快)。他们对速度很着迷,会用任何东西来获得性能。

除非你以数千次/秒的速度运行该选择器,否则我真的不会太担心它。

如果您真的担心,请尝试进行一些基准测试,看看哪个更快。

答案 8 :(得分:0)

考虑使用Oliver Steele的Sequential库来调用方法,而不是一次性调用方法。

http://osteele.com/sources/javascript/sequentially/

“最终”方法可帮助您在初始调用后的一段时间后调用方法。 “顺序”方法允许您在一段时间内对多个任务进行排队。

非常有帮助!

答案 9 :(得分:0)

我问的问题great tip:尽可能使用标准CSS选择器。这允许jQuery使用Selectors API。根据{{​​3}},这会导致选择器接近原生性能。应避免使用:has():contains()等功能。

我的研究支持Selectors API随jQuery 1.2.7,Firefox 3.1,IE 8,Opera 10,Safari 3.1一起推出。

答案 10 :(得分:0)

如果我没弄错的话,jQuery也是一个自下而上的引擎。这意味着$('#foo bar div')$('bar div #foo')慢得多。例如,$('#foo a')将遍历页面上的所有a元素,并查看它们是否具有#foo的祖先,这使得此选择器极其低效。

Resig可能已经针对这种情况进行了优化(如果他这样做,我也不会感到惊讶 - 我相信他是在他的Sizzle引擎中做的,但我不是100%肯定的。)

答案 11 :(得分:0)

我认为首先按ID选择总是更快:

$("#myform th").css("color","red");

应该比

更快
$("th").css("color","red");

但是,我想知道从ID开始有多少链接有用?这是

$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");

比这更快吗?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");