jQuery不同選擇器性能比較
有大量的日志文章論述了jQuery選擇器及它們的性能影響。正如你所知,可以通過ID, TagName或ClassName選擇元素。依賴于不同的選擇器,jQuery會使用瀏覽器本地方法,如通過ID或標簽來選擇元素,或者在使用類名選擇時須手工從DOM中遍歷獲得元素(因為在IE中不存在相應的 getElementsByClssName)。
分析我的頁面時間中這2秒
在onLoad處理器中對頁面中某些特定的元素使用jQuery設置為隱藏,顯示或改變樣式表。這里是一個代碼片斷:
onLoad中的jQuery腳本樣例
onLoad中的jQuery腳本樣例
在onLoad事件處理器中充滿著這樣的調(diào)用。通過使用免費的dynaTrace AJAX Edition, 你會看到被解析為選擇器的$調(diào)用,并跟隨著那些方法調(diào)用,選擇器至少都能獲取到一個對象。下面通過PurePath對onLoad事件處理器的觀察,不僅給我們展示了每次選擇器調(diào)用所耗費的時間,還包括在不只一個對象時實際找到的對象數(shù)(下面還沒有哪個方法調(diào)用是連一個對象都找不到的)。
非必要的jQuery選擇器調(diào)用導致無謂的開銷
所有紅色標記的調(diào)用都未返回一個元素,因為不存在直接基于查詢條件的DOM元素。JavaScript列顯示了每一次單獨方法調(diào)用的執(zhí)行時間–范圍在 1ms 到大于 100 ms。Size列告訴了我們每次單獨的調(diào)用產(chǎn)生了多少次的JavaScript/DOM的方法調(diào)用(譯者注:指瀏覽器本地的調(diào)用)。這里我們也能明白,為什么某些 $ 調(diào)用花費了那么長時間,是因為它們實際進行了許多的調(diào)用來完成請求。Invocation 列告訴了我們該方法被它的父級所調(diào)用的頻度。這里我們可看出一些對象實際被解析了多次,比如: “.pop-cart”。***的做法應該是只解析一次得到對象并緩存起來。
這里我們學到的***課是上面多數(shù)調(diào)用是非必要的,只會產(chǎn)生過量的消耗。如果你明確知道你需要解析出哪些頁面元素,那就不要試圖去解析其他的對象。我知道,用全局的腳本文件來處理不同頁面中的不同內(nèi)容會導致出現(xiàn)這樣的情況–但是–你是否真愿意在這種無謂的開銷中生活呢?
分析jQuery選擇器的差異
在分析頁面上的***個問題是致使了太多的非必要$調(diào)用。繼而帶來的另一個疑問就是為何某些$方法響應很快(幾微秒),而有些卻用了相當長的時間(超過100ms)?;氐轿业捻撁嬷衼?,它向我提示了如下的結論:
ID選擇器,也就是使用了getElementById,是最快的
下圖展示了一個使用ID的選擇器。它使用了getElementById,因此很快就返回了。
jQuery ID選擇器
TagName選擇器使用的是getElementsByTagName
下面的例子是通過TagName搭配ClassName 來選擇元素。jQuery首先使用本地實現(xiàn)getElementsByTagName來獲得所有指定標簽的元素。接著遍歷它們針對ClssName進行過濾。
ClassName選擇器需要遍歷所有的DOM元素
如果你只用ClassName選擇器 - jQuery需要遍歷DOM中的每一個元素,因為在Internet Explorer(對于FireFox是另一番情景)中沒有對應于 getElementsByClassName的本地實現(xiàn)。下圖顯示了在一直有著3460個DOM元素的頁面中選擇器使用開銷的情況。
jQuery ClassName選擇器
小結
依賴于你的Web站點的大小(指DOM元素的數(shù)量), 你需要考慮每個單獨的選擇器方法的開銷。相比于通過ClassName來選擇,你應該優(yōu)先考慮用TagName 搭配ClassName來選擇,或是在你的頁面只有少量對象時用唯一性的ID來選擇。而且- 確保緩存了已解析獲得的對象,以避免再次解析調(diào)用時的開始。還有 – ***也是應該予以重視的一點 – 避免不必要的調(diào)用。如前面頁面我所分析的 – 2 秒中有超過1.5秒是可以規(guī)避那些調(diào)用來省去的。
譯文鏈接:http://www.blogjava.net/Unmi/archive/2009/11/24/303477.html
原文鏈接:http://blog.dynatrace.com/2009/11/09/101-on-jquery-selector-performance/
【編輯推薦】