今天发现了一个新的API用来获取页面中的节点元素querySelector
和querySelectorAll
,他们的作用和getElementByXXX
系列是一样的。下面看一下这个新方法的性能如何。
程序执行时间测试方法
先来科普一下如何看某段程序的运行时间。其实方法很简单:
像上面这样我们就可以获取到函数的运行时间
构造测试环境
为了使测试效果更明显,我们先构造一个巨大的DOM树:
|
|
这样我们就得到了一个内部有5W个span
元素的DOM树结构
下面我们将比较querySelectorAll()
方法和getElementsByTagName()
方法的性能
性能测试
|
|
可以看到我们在执行要比较的两个函数之前和之后分别调用了new Date()
来获取当前时刻,他们的差值就是两个函数获取节点所需的信息;后面我们又对获取到的节点进行了赋值操作。
最后输出时间间隔
|
|
每次结果都有些差异,我截取了其中一个结果
我们可以看到,使用getElementsByTagName
方法,在获取节点的过程中,性能是相当好的,获取5W个节点的集合,时间基本不会超过1ms,相对来说querySelectorAll
方法的性能就稍差一些;这么说来querySelectorAll
的出现就没有意义了吗?答案是否定的。我们可以观察到,如果对获取到的节点集合进行简单的操作,getElementsByTagName
消耗的时间会很长,而querySelectorAll
几乎不消耗时间,这是为什么呢?
原理
当我们在使用getElementsByClassName
方法的时候,我们得到的节点集合是实时
的,也就是说,每次对集合进行操作之前,都会重新遍历一遍节点以获取DOM树中最新
的状态,可以理解为获得了节点集合的引用
;而querySelectorAll
方法正相反,其获得的是DOM树中当前时刻节点集合的快照
,是静态的值。
结论
于是我们可以得出结论,如果只要单纯的获取DOM树中节点的集合,而不需要改变节点元素的时候,getElementsByClassName
方法的速度要快很多;如果要对集合中的节点元素进行批量操作的时候,可以选择使用querySelectorAll
方法来提高性能
转载请注明出处 http://cthblog.cn/2017/03/07/querySelector-vs-dom-method/