新選擇器querySelector家族的一些研究
第一個(gè)大問(wèn)題:
拜讀大神之后有一段話很值得玩味:
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.
冒昧翻譯:
需要強(qiáng)調(diào)下,返回值(querySelectorAll的)的確是帶有所有期望的屬性和方法的Nodelist。但是它的底層實(shí)現(xiàn)是一個(gè)元素的快照,而并非一個(gè)不斷對(duì)document進(jìn)行重復(fù)執(zhí)行的動(dòng)態(tài)查詢。這個(gè)實(shí)現(xiàn)消除了大部分與Nodelist對(duì)象的使用相關(guān)的性能開(kāi)銷。
這句話作何理解呢?!為此寫(xiě)了一個(gè)Demo,直接看DEMO
代碼中,分別用querySelectorAll和getElementsByTagName分別獲取body下面的div元素,然后先后兩次在第一個(gè)元素前面插入一個(gè)新的div。
然后觀察之前查詢結(jié)果中的length的值和第一個(gè)元素的變化。
結(jié)論是query的結(jié)果始終都是一個(gè)值,一直都沒(méi)有變;而get結(jié)果的值卻會(huì)隨著每次的操作變化而變化。
這時(shí)候再來(lái)理解上面說(shuō)的快照和動(dòng)態(tài)查詢,query就對(duì)應(yīng)著是快照,一旦查詢,之后再怎么變都與我無(wú)關(guān);get就對(duì)應(yīng)的是動(dòng)態(tài)查詢,會(huì)隨著document的變化而變化。
第二個(gè)大問(wèn)題:性能問(wèn)題
寫(xiě)了一個(gè)Demo,兩個(gè)方法同時(shí)查詢一個(gè)ID為test的div,各自執(zhí)行5000次。反復(fù)刷新5次,取平均值。
手機(jī)端谷歌瀏覽器:
Get | Query | 差值 | |
第1次 | 25 | 12 | 13 |
第2次 | 9 | 13 | -4 |
第3次 | 11 | 18 | -7 |
第4次 | 77 | 26 | 51 |
第5次 | 13 | 26 | -13 |
總計(jì) | 135 | 85 | 50 |
平均下來(lái)每次運(yùn)算get要比query慢10(ms),并且get方法在谷歌瀏覽器上面變現(xiàn)的不是很穩(wěn)定,安卓默認(rèn)瀏覽器也有類似的表現(xiàn)。
手機(jī)端UC瀏覽器:
Get | Query | 差值 | |
第1次 | 5 | 163 | -158 |
第2次 | 6 | 147 | -141 |
第3次 | 5 | 138 | -133 |
第4次 | 5 | 142 | -137 |
第5次 | 5 | 158 | -153 |
總計(jì) | 26 |
算了平均值不統(tǒng)計(jì)了,結(jié)論很明顯Query的性能要比get差很多。
看來(lái)在UC瀏覽器上還是不要使用Query了,性能差距太大了。