新选择器querySelector家族的一些研究

欢欢欢欢 发表于 2016-4-23 16:00

第一个大问题:

拜读大神之后有一段话很值得玩味:

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了,性能差距太大了。

除了这两点,他们之间还有不同吗?个人感觉,Query将来的性能会越来越好的,但是目前各大厂商还没有统一,目前除非有些很特殊的需求,否则使用Query方法还为时过早。