提高 jQuery 选择器性能的好方法?

IT技术 javascript jquery performance css-selectors
2021-01-24 22:42:38

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

$("div.myclass")不是快$(".myclass")

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

6个回答

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

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

但即使浏览器实现了该功能,按标签名称过滤仍然会更快,对吗?
2021-03-17 22:42:38
我已经更新了 Jeffs 响应中的componenthouse.com/article-19以使用最新的 jQuery,从第二个测试来看,A 和 B 在 Opera 10 和 firefox 3.5 中的性能似乎相同。我不能让它在 IE8 上工作(虽然我没有尝试太多)。所以我之前的评论似乎是错误的。
2021-03-29 22:42:38
@AlienWebguy:您的测试不能准确表示具有许多 DOM 元素的大页面。凭借更简单的过滤器集,您的测试速度更快,而不是更快的查找。
2021-03-30 22:42:38
@hoffmann,可能不是。如果我们假设这两个函数都是用 b 树实现的,我不明白为什么 getElementsByClassName 会更慢......你仍然需要在能够使用该函数之前构建索引......
2021-03-31 22:42:38
@AlienWebguy:这个答案的重点是某些浏览器不支持getElementsByClassName,这意味着页面上的每个元素都需要针对该类进行测试。请记住,这个答案也在 08 年给出。;o)
2021-04-08 22:42:38

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

$(".myclass", a_DOM_element);

应该比

$(".myclass");

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

我记得$('.myclass', a_DOM_element)jQuery 转换为/调用,$(a_DOM_element).find('.myclass')因此简单地使用而不是像第一个示例那样建立选择器上下文可能会稍微快find()一些
2021-03-16 22:42:38

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

这意味着$('#foo bar div')$('bar div #foo')

这不是重点。如果你有#foo,无论如何你都不会在选择器之前放置任何东西,因为 ID 必须是唯一的。

重点是:

  • 如果你是从一个ID元素subselecting什么,然后选择后,然后再使用.find.children等:$('#foo').find('div')
  • 选择器的最左边(第一)部分可能效率较低,缩放到最右边(最后)部分应该是最有效的 - 这意味着如果您没有 ID,请确保您正在寻找$('div.common[slow*=Search] input.rare')而不是$('div.rare input.common[name*=slowSearch]')- 因为这不是' t 始终适用确保通过相应的拆分来强制选择器顺序。

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

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

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

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

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

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

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

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

  • 尽可能按 #id 选择(性能测试结果约快 250)
  • 指定选择范围 ( $('.select', this))