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

时间:2020-03-05 18:48:20  来源:igfitidea点击:

我正在寻找可以改善jQuery调用选择器性能的任何方式。具体来说是这样的:

$(" div.myclass")`比$("。myclass")快吗?

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

解决方案

回答

我去过一些jQuery邮件列表,从我在那儿读到的内容来看,它们很可能按标记名和类名进行过滤(反之亦然,如果速度更快)。他们对速度很着迷,会使用任何东西来获得出色的性能。

除非我们以每秒数千次的速度运行该选择器,否则我真的不会为此担心太多。

如果我们真的很担心,请尝试做一些基准测试,看看哪个更快。

回答

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

在所有浏览器都本机实现getElementsByClassName之前,情况就是如此,与getElementsByTagName一样。

回答

我要补充说明的是,在99%的Web应用程序中,即使是Ajax繁重的应用程序,Web服务器的连接速度和响应速度都将提高应用程序而不是JavaScript的性能。我并不是说我们应该故意编写缓慢的代码,或者一般而言,意识到哪些事情可能比其他事情更快会不好。

但是我想知道我们是要解决尚不存在的问题,还是要针对可能在不久将来发生变化的问题进行优化(例如,是否有更多的人开始使用支持`前面提到的getElementsByClassName()函数),实际上使优化后的代码运行得更慢。

回答

考虑使用Oliver Steele的Sequentially库来逐步调用方法,而不是一次调用所有方法。

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

"最终"方法可在从初始调用开始的一段时间后调用该方法。 "顺序"方法使我们可以在一段时间内将多个任务排队。

很有帮助!

回答

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

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

这样可以很好地降低ID选择器,类选择器和选择器前缀标签名称的速度。

ID最快的选择器是:$("#id")

最快的分类选择器是:$('tag.class')

因此,仅在按班级选择时,按标签前缀才有用!

回答

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

$(".myclass", a_DOM_element);

应该比

$(".myclass");

如果我们已经有a_DOM_element,并且它比整个文档小得多。

回答

以下是提高jQuery选择器性能的方法:

  • 尽可能通过#id选择(性能测试结果快250左右)
  • 指定选择范围($('。select',this))

回答

为了完全理解更快的速度,我们必须了解CSS解析器是如何工作的。

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

某些选择器(例如ID和TagName)使用浏览器的本机实现,速度更快。而其他类(例如类和属性)是分别编程的,因此速度较慢,这需要循环遍历选定的元素并检查每个类的名称。

所以可以回答问题:

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

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

由于所有javascript库都基于jQuery,因此它比jQuery传播得更远。唯一的其他选择是使用xPath,但目前并不是所有浏览器都很好地支持它。

回答

我问的一个问题的一个很好的技巧:尽可能使用标准CSS选择器。这允许jQuery使用Selectors API。根据约翰·雷西格(John Resig)进行的测试,选择器的性能接近于本机。应该避免使用诸如:: has()和:contains()之类的函数。

从我的研究中开始,jQuery 1.2.7,Firefox 3.1,IE 8,Opera 10,Safari 3.1引入了对Selectors API的支持。

回答

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

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

回答

我相信按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");

回答

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

that means $('#foo bar div') is a
  lot slower than $('bar div #foo')

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

重点是:

  • 如果要从具有ID的元素中选择任何内容,则先选择后者,然后使用.find,.children等:$('#foo')。find('div')
  • 选择器的最左(第一)部分的效率可能会降低,而缩放到最右(最后)的部分应该是效率最高的-这意味着如果我们没有ID,请确保我们正在寻找$( [slow * = Search] input.rare')而不是$('div.rare input.common [name * = slowSearch]')`-因为这并不总是适用,请确保按以下方式强制选择器顺序相应地拆分。