jQuery遍历首选的select器?
使用$("#vacations").find("li").last()
比$("#vacations li:last")
更好吗?
背景和我的想法:
我正在玩一个很好的交互式尝试jQuery教程 ,其中一个任务说:
当你浏览你的代码时,你注意到别人正在用:$(“#vacations li:last”)来select最后一个假期。 你看看这个,你会想:“遍历会让这个更快!” 你应该对这些想法采取行动,重构这段代码,以便使用遍历来查找#vacations中的最后一个li。
我为什么这么想? 对我来说,select器的使用看起来比遍历更高一些。 在我心中,当我指定一个select器是由jQuery如何更好地得到我需要的单一结果(无需返回中期结果)。
什么是使用复合select器额外的开销? 是否因为select器逻辑的当前实现只是parsingstring并使用遍历API? parsing一个缓慢的string? 未来的实现是否有可能使用这样一个事实,即它不需要返回中间结果,而且比遍历快呢?
对此,我们没有切入点,但是对于您使用的:last
select器,这是对Selectors API标准的专有扩展。 因此,使用本机.querySelectorAll
方法是无效的。
Sizzle所做的基本上是尝试在.querySelectorAll
使用select器,如果由于select器无效而抛出exception,它将默认为纯粹的基于JavaScript的DOMselect/过滤。
这意味着包括select器,如:last
会导致你不能获得本地代码DOMselect的速度提升。
此外,还包括优化,以便当您的select器非常简单,如只是一个ID或元素名称,将使用本机getElementById
和getElementsByTagName
,这是非常快的; 通常甚至比querySelectorAll
更快。
由于.last()
方法只是抓取集合中的最后一个项目,而不是过滤所有项目,这是Sizzlefilter通常所做的(至less他们曾经这么做) ,这也会提高。
国际海事组织,远离专有的东西。 现在.querySelectorAll
几乎无处不在,只有使用符合标准的select器才有真正的优势。 DOMselect后进行任何进一步的过滤。
在$("#vacations").find("li")
,不要担心中期结果。 这将使用getElementById
和getElementsByTagName
,并且将会非常快。
如果你真的超级关心速度,减less使用jQuery,并直接使用DOM。
您现在可以在文档中findselect器的注释,例如:last
,提醒您关于性能的损失:
因为:last是jQuery扩展,而不是CSS规范的一部分,使用
:last
查询不能利用本地DOMquerySelectorAll()
方法提供的性能提升。 为了在使用时达到最佳性能:last
select元素,首先使用纯CSSselect器select元素,然后使用.filter(":last")
。
但是我不同意.filter(":last")
是一个很好的替代品。 更好的方法就像.last()
,将直接针对元素,而不是过滤集。 我有一种感觉,他们只是希望人们继续使用不符合标准的select器。 国际海事组织,你最好忘了他们。
这是你的设置testing: http : //jsperf.com/andrey-s-jquery-traversal
jQuery的select器引擎嘶嘶作响 ,用正则expression式分析string,并试图通过使用getElementById
和getElementsByTagName
来加速非常基本的select器。 如果你的select器比#foo
和img
更复杂,它将尝试使用querySelectorAll
,它只接受有效的CSSselect器(no :radio
, :eq
, :checkbox
或其他jQuery特定的伪select器)。
select器string的可读性和速度都较慢,所以没有理由使用它。
通过将select器string分解为Sizzle可以快速parsing的简单块( #id
和tagname
),您基本上只需将getElementById
和getElementsByTagName
链接在一起即可。