[英]Is jQuery traversal preferred over selectors?
使用$("#vacations").find("li").last()
比$("#vacations li:last")
更好嗎?
背景和我的想法:
我在玩一個不錯的交互式嘗試jQuery教程 ,其中一項任務說:
在查看代碼時,您會注意到其他人正在使用$(“#vacations li:last”)選擇最后一個假期。 您看了一下,就會想到:“ Traversal可以使這種方式更快!” 您應該根據這些想法采取行動,重構代碼以使用遍歷在#vacations中找到最后一個li。
我為什么會這樣呢? 對我來說,選擇器的使用水平比遍歷更高。 在我的腦海中,當我指定一個選擇器時,取決於jQuery如何更好地獲得所需的單個結果(無需返回臨時結果)。
使用復合選擇器的額外開銷是多少? 是否因為選擇器邏輯的當前實現只是解析字符串並使用遍歷API? 解析字符串的速度很慢嗎? 將來的實現是否有可能利用這樣的事實,即它不需要返回臨時結果,並且比遍歷更快?
對此並沒有干脆的答案,但是相對於您使用的:last
選擇器,它是Selectors API標准的專有擴展。 因此,與本機.querySelectorAll
方法一起使用無效。
Sizzle所做的基本上是嘗試將您的選擇器與.querySelectorAll
一起使用,如果由於選擇器無效而引發異常,則它將默認為純基於JavaScript的DOM選擇/過濾。
這意味着包括:last
這樣的選擇器將使您無法通過本機代碼提高DOM選擇的速度。
此外,還包括一些優化,以便當選擇器非常簡單時(如ID或元素名稱),將使用本機的getElementById
和getElementsByTagName
,這非常快; 通常甚至比querySelectorAll
更快。
而且由於.last()
方法僅.last()
集合中的最后一個項目而不是過濾所有項目,這是Sizzle過濾器通常會執行的操作(至少以前是這樣做的) ,這也會.last()
。
IMO,請遠離專有內容。 現在, .querySelectorAll
幾乎無處不在,僅使用符合標准的選擇器具有真正的優勢。 對DOM選擇進行進一步過濾。
在$("#vacations").find("li")
,不必擔心中間結果。 這將使用getElementById
后跟getElementsByTagName
,並且將非常快。
如果您真的非常關心速度,請減少對jQuery的使用,然后直接使用DOM。
當前,您會在文檔中找到有關選擇器的說明,例如:last
,它們會警告您性能損失:
因為:last是jQuery擴展,而不是CSS規范的一部分,所以使用
:last
查詢不能利用本機DOMquerySelectorAll()
方法提供的性能提升。 為了在使用:last
選擇元素時達到最佳性能,請首先使用純CSS選擇器選擇元素,然后使用.filter(":last")
。
但是我不同意.filter(":last")
是一個很好的替代品。 更好的方法是.last()
類的方法,該方法將直接定位元素而不是過濾集合。 我感覺他們只是希望人們繼續使用不符合標准的選擇器。 IMO,最好不要忘記它們。
這是您設置的測試: http : //jsperf.com/andrey-s-jquery-traversal
jQuery的選擇器引擎Sizzle使用正則表達式解析字符串,並嘗試通過使用getElementById
和getElementsByTagName
加速非常基本的選擇器。 如果您的選擇器比#foo
和img
復雜,它將嘗試使用querySelectorAll
,它僅接受有效的CSS選擇器(no :radio
, :eq
, :checkbox
或其他jQuery特定的偽選擇器)。
選擇器字符串的可讀性較低且較慢,因此實際上沒有理由使用它。
通過將選擇器字符串分解為Sizzle可以快速解析的簡單塊( #id
和tagname
),您基本上就可以#id
getElementById
和getElementsByTagName
調用鏈接在一起,這與您獲得的速度#id
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.