新選擇器querySelector家族的一些研究
第一個大問題:
拜讀大神之后有一段話很值得玩味:
To clarify, the return value is actually a NodeList with all of the expected properties and methods, but its underlying implementation acts as a snapshot of elements rather than a dynamic query that is constantly reexecuted against a document. This implementation eliminates most of the performance overhead associated with the use of NodeList objects.
冒昧翻譯:
需要強調下,返回值(querySelectorAll的)的確是帶有所有期望的屬性和方法的Nodelist。但是它的底層實現是一個元素的快照,而并非一個不斷對document進行重復執行的動態查詢。這個實現消除了大部分與Nodelist對象的使用相關的性能開銷。
這句話作何理解呢?!為此寫了一個Demo,直接看DEMO
代碼中,分別用querySelectorAll和getElementsByTagName分別獲取body下面的div元素,然后先后兩次在第一個元素前面插入一個新的div。
然后觀察之前查詢結果中的length的值和第一個元素的變化。
結論是query的結果始終都是一個值,一直都沒有變;而get結果的值卻會隨著每次的操作變化而變化。
這時候再來理解上面說的快照和動態查詢,query就對應著是快照,一旦查詢,之后再怎么變都與我無關;get就對應的是動態查詢,會隨著document的變化而變化。
第二個大問題:性能問題
寫了一個Demo,兩個方法同時查詢一個ID為test的div,各自執行5000次。反復刷新5次,取平均值。
手機端谷歌瀏覽器:
Get | Query | 差值 | |
第1次 | 25 | 12 | 13 |
第2次 | 9 | 13 | -4 |
第3次 | 11 | 18 | -7 |
第4次 | 77 | 26 | 51 |
第5次 | 13 | 26 | -13 |
總計 | 135 | 85 | 50 |
平均下來每次運算get要比query慢10(ms),并且get方法在谷歌瀏覽器上面變現的不是很穩定,安卓默認瀏覽器也有類似的表現。
手機端UC瀏覽器:
Get | Query | 差值 | |
第1次 | 5 | 163 | -158 |
第2次 | 6 | 147 | -141 |
第3次 | 5 | 138 | -133 |
第4次 | 5 | 142 | -137 |
第5次 | 5 | 158 | -153 |
總計 | 26 |
算了平均值不統計了,結論很明顯Query的性能要比get差很多。
看來在UC瀏覽器上還是不要使用Query了,性能差距太大了。