我正在寻找任何可以提高 jQuery 调用的选择器性能的方法。特别是像这样的事情:
$("div.myclass")比 $(".myclass")快
$("div.myclass")
$(".myclass")
我认为它可能是,但我不知道 jQuery 是否足够聪明,可以首先通过标签名来限制搜索,等等。有人知道如何构造一个最佳性能的 jQuery 选择器字符串吗?
我曾经参与过一些 jQuery 邮件列表,从我在那里读到的内容来看,它们很可能按照标记名然后类名进行过滤(如果过滤速度更快的话,反之亦然)。他们痴迷于速度,并且会不惜一切代价来获得一点点的表现。
我真的不会担心它太多,除非你运行该选择器数千次/秒。
如果你真的很担心,试着做一些基准测试,看看哪个更快。
毫无疑问,首先通过标记名进行过滤要快得多比按类名过滤。
直到所有浏览器本机实现 getElementsByClassName 之前都是这样,getElementsByTagName 就是这种情况。
我要补充一点,在99% 的 Web 应用程序中,即使是 Ajax 很重的应用程序,网络服务器的连接速度和响应都会影响应用程序的性能,而不是 javascript。我并不是说你应该故意编写较慢的代码,或者通常意识到什么东西可能比其他东西更快是不好的。
但是我想知道你是否正在尝试解决一个实际上并不存在的问题,或者即使你正在优化一些可能在不久的将来 改变的东西(比如,如果更多的人开始使用一个支持前面提到的 getElementsByClassName()功能的浏览器) ,使得你优化的代码实际上运行得更慢。
getElementsByClassName()
可以考虑使用 Oliver Steele 的 Sequential 库随着时间的推移调用方法,而不是一次调用所有方法。
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");
如果您已经有一个 _ DOM _ 元素,并且它明显小于整个文档。
下面是如何提高 jQuery 选择器的性能:
$('.select', this)
为了完全理解什么更快,您必须理解 CSS 解析器是如何工作的。
您传入的选择器将使用 RegExp 分割成可识别的部分,然后逐块处理。
一些选择器,如 ID 和 TagName,使用浏览器的本机实现,这是更快的。而类和属性等其他类则是单独编程的,因此速度要慢得多,需要遍历选定的元素并检查每个类名。
回答你的问题:
$(‘ tag.class’)比 $(‘ . class’)快。为什么? 对于第一种情况,jQuery 使用本机浏览器实现将选择过滤到您需要的元素。只有这样它才会发射得更慢。类实现过滤到您要求的内容。
在第二种情况下,jQuery 使用它的方法通过抓取类来过滤每个元素。
因为所有的 javascript 库都是基于这个的,所以这比 jQuery 传播得更广。唯一的其他选择是使用 xPath,但是目前它在所有浏览器中都没有得到很好的支持。
我问的一个问题的 好建议: 尽可能使用 标准 CSS 选择器。这允许 jQuery 使用 选择器 API。根据 由 John Resig 执行的测试,这将导致选择器的近本机性能。应该避免使用诸如 :has()和 :contains()之类的函数。
:has()
:contains()
从我对 Selectors API 的研究支持来看,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的祖先,这使得这个选择器极其低效。
$('#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");
如上所述,jQuery 是自底向上工作的
这意味着 $('#foo bar div')是一个 比 $('bar div #foo')慢很多
这不是重点。如果使用 #foo,那么无论如何都不会在选择器中放置任何内容,因为 ID 必须是唯一的。
重点是:
.find
.children
$('#foo').find('div')
$('div.common[slow*=Search] input.rare')
$('div.rare input.common[name*=slowSearch]')