74

我正在寻找可以提高 jQuery 调用的选择器性能的任何方法。具体是这样的:

$("div.myclass")比_$(".myclass")

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

4

12 回答 12

36

毫无疑问,首先按标签名过滤比按类名过滤要快得多。

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

于 2008-09-05T16:39:39.383 回答
14

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

$(".myclass", a_DOM_element);

应该比

$(".myclass");

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

于 2008-12-20T01:16:19.090 回答
5

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

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

一些选择器,如 ID 和 TagName,使用浏览器的本地实现,速度更快。而像类和属性这样的其他类是单独编程的,因此速度要慢得多,需要遍历选定的元素并检查每个类名。

所以是的,回答你的问题:

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

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

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

于 2009-05-13T15:16:22.647 回答
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]')- 因为这不是t 始终适用确保通过相应的拆分来强制选择器顺序。
于 2010-11-06T15:11:57.150 回答
4

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

  • 尽可能按 #id 选择(性能测试结果快约 250)
  • 指定您的选择范围 ( $('.select', this))
于 2009-01-06T11:13:23.530 回答
3

我要补充一点,在 99% 的 Web 应用程序中,即使是 ajax 重度应用程序,Web 服务器的连接速度和响应将推动您的应用程序的性能,而不是 javascript。我并不是说您应该故意编写慢代码,或者通常意识到哪些事情可能比其他事情更快是不好的。

但是我想知道您是否正在尝试解决一个尚不存在的问题,或者即使您正在针对在不久的将来可能会发生变化getElementsByClassName()的事情进行优化(例如,如果更多人开始使用支持功能的浏览器前面提到的),使您的优化代码实际上运行得更慢。

于 2008-10-20T15:37:06.607 回答
3

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

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

这可以很好地降低按 id 选择器、按类选择器和选择器前缀标记名称的速度。

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

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

因此,只有在按类别选择时,才能使用标签前缀!

于 2008-12-20T00:45:20.527 回答
0

我一直在一些 jQuery 邮件列表中,从我在那里读到的内容来看,它们很可能是按标签名然后类名过滤(反之亦然,如果它更快的话)。他们对速度非常着迷,并且会使用任何东西来获得一点性能。

除非您每秒运行该选择器数千次,否则我真的不会太担心它。

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

于 2008-09-05T16:32:25.657 回答
0

考虑使用 Oliver Steele 的 Sequentially 库随时间调用方法,而不是一次调用所有方法。

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

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

很有帮助!

于 2008-12-20T00:36:28.577 回答
0

我问的一个问题的一个很好的提示:尽可能使用标准的 CSS 选择器。这允许 jQuery 使用Selectors API。根据John Resig 执行的测试,这导致选择器的性能接近原生。:has():contains()应该避免的功能。

根据我的研究,jQuery 1.2.7、Firefox 3.1、IE 8、Opera 10、Safari 3.1 引入了对 Selectors API 的支持。

于 2010-01-14T03:30:17.570 回答
0

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

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

于 2010-01-14T03:39:33.003 回答
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");
于 2010-02-12T23:59:01.123 回答