我正在寻找可以提高 jQuery 调用的选择器性能的任何方法。具体是这样的:
$("div.myclass")
比_$(".myclass")
我想可能是这样,但我不知道 jQuery 是否足够聪明,可以先通过标签名称限制搜索,等等。有人对如何制定 jQuery 选择器字符串以获得最佳性能有任何想法吗?
我正在寻找可以提高 jQuery 调用的选择器性能的任何方法。具体是这样的:
$("div.myclass")
比_$(".myclass")
我想可能是这样,但我不知道 jQuery 是否足够聪明,可以先通过标签名称限制搜索,等等。有人对如何制定 jQuery 选择器字符串以获得最佳性能有任何想法吗?
毫无疑问,首先按标签名过滤比按类名过滤要快得多。
在所有浏览器本机实现 getElementsByClassName 之前,情况都会如此,就像 getElementsByTagName 的情况一样。
在某些情况下,您可以通过限制其上下文来加速查询。如果您有元素引用,则可以将其作为第二个参数传递以限制查询的范围:
$(".myclass", a_DOM_element);
应该比
$(".myclass");
如果您已经有 a_DOM_element 并且它比整个文档小得多。
为了完全理解什么是更快,你必须了解 CSS 解析器是如何工作的。
您传入的选择器会使用 RegExp 拆分为可识别的部分,然后逐个处理。
一些选择器,如 ID 和 TagName,使用浏览器的本地实现,速度更快。而像类和属性这样的其他类是单独编程的,因此速度要慢得多,需要遍历选定的元素并检查每个类名。
所以是的,回答你的问题:
$('tag.class') 比 $('.class') 更快。为什么?对于第一种情况,jQuery 使用本机浏览器实现将选择过滤到您需要的元素。只有这样,它才会启动较慢的 .class 实现,过滤到您要求的内容。
在第二种情况下,jQuery 使用它的方法通过抓取类来过滤每个元素。
这比 jQuery 传播得更远,因为所有 javascript 库都基于此。唯一的其他选择是使用 xPath,但目前所有浏览器都不太支持它。
正如上面 Reid 所说,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]')
- 因为这不是t 始终适用确保通过相应的拆分来强制选择器顺序。以下是提高 jQuery 选择器性能的方法:
$('.select', this)
)我要补充一点,在 99% 的 Web 应用程序中,即使是 ajax 重度应用程序,Web 服务器的连接速度和响应将推动您的应用程序的性能,而不是 javascript。我并不是说您应该故意编写慢代码,或者通常意识到哪些事情可能比其他事情更快是不好的。
但是我想知道您是否正在尝试解决一个尚不存在的问题,或者即使您正在针对在不久的将来可能会发生变化getElementsByClassName()
的事情进行优化(例如,如果更多人开始使用支持功能的浏览器前面提到的),使您的优化代码实际上运行得更慢。
另一个查找性能信息的地方是 Hugo Vidal Teixeira 的选择器性能分析页面。
http://www.componenthouse.com/article-19
这可以很好地降低按 id 选择器、按类选择器和选择器前缀标记名称的速度。
id 最快的选择器是:$("#id")
按类别最快的选择器是:$('tag.class')
因此,只有在按类别选择时,才能使用标签前缀!
我一直在一些 jQuery 邮件列表中,从我在那里读到的内容来看,它们很可能是按标签名然后类名过滤(反之亦然,如果它更快的话)。他们对速度非常着迷,并且会使用任何东西来获得一点性能。
除非您每秒运行该选择器数千次,否则我真的不会太担心它。
如果您真的很担心,请尝试进行一些基准测试,看看哪个更快。
考虑使用 Oliver Steele 的 Sequentially 库随时间调用方法,而不是一次调用所有方法。
http://osteele.com/sources/javascript/sequentially/
“最终”方法可帮助您在初始调用后的一段时间后调用方法。“顺序”方法让您可以在一段时间内对多个任务进行排队。
很有帮助!
我问的一个问题的一个很好的提示:尽可能使用标准的 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");