我试图找到一个元素:
doc.querySelectorAll('#divContentList article');
它运作良好,但另一位开发人员告诉我,我应该写:
doc.querySelector('#divContentList').querySelectorAll('article');
他说这更好,因为它直接转到#divContentList
,然后查找article
元素。
我不认为他的解决方案是速度性能最好的,它会搜索元素两次。
我认为querySelectorAll
非常棒,可以完成它的工作。
主要问题是,哪一行代码总体上最好?
答案 0 :(得分:2)
这个问题的答案是:
问题是答案可能会随着时间而改变。浏览器供应商倾向于优化大量使用的方法。如果方法1被大量使用,它可能会更快,或者将来更快。
这两种方法看起来都与我相同(使用给定的输入)。如果有一个基本的根本原因,为什么一个应该更快:使用更快的方法。
由于你的第一场比赛是一场比赛,所以总是只有一场比赛。
如果您的查询为".parent .child"
且有许多家长没有孩子,则".parent .child"
可能比<{1}}更快。
答案 1 :(得分:2)
感谢Mauricio Soares和他的jsPerf第一个例子:
<div id="divContentList">
<article></article>
</div>
确实是第一种方法:
doc.querySelectorAll('#divContentList article');
如果其中只有一个article
,则速度更快。
我已将jsPerf修改为10,然后修改为1000 article
,性能差异非常大。 Check it here
<div id="divContentList">
<article></article>
...
<article></article>
</div>
这将导致我的问题的第二种方法:
doc.querySelector('#divContentList').querySelectorAll('article');
更快
最后,使用getElementById
表现的效果略有提升
doc.getElementById('divContentList').querySelectorAll('article');
那是最好的表现
Keith Rousseau正确querySelectorAll
从右到左进行评估。
修改强>:
我也发现了querySelector
和getElementById/getElementsByTagName
的不同之处。 querySelector返回Static NodeList,而getElementById返回Live NodeList。
我做了另一个test
document.getElementById('divContentList').getElementsByTagName('article');
这个蛋糕。差别很荒谬
答案 2 :(得分:1)
querySelectorAll从右到左进行求值,因此第一个将查找页面上的所有文章,然后将其过滤到divContentList下面的文章。我会为id获取getElementById,然后找到下面的文章。
但正如其他人所说,测试它。并在多个浏览器中进行测试。
答案 3 :(得分:0)
您可以使用jsPerf进行此类测试......
我已经使用您的用例here设置了一个简单的性能测试,似乎它们具有相似的性能,“单个”querySelector似乎有点更多的性能,但我不要以为在你的申请中这根本不是问题。
答案 4 :(得分:0)
当然,这是一个老问题,但是偶然发现了这个问题,感觉就像是在权衡一下。提前提醒我一个大注意事项是:这两个语句不是,我认为没有人钻研过。在技术上是的同义词。这可以解释总体性能差异。
最简单的示例实际上是YouTube。如果您观看任何视频,都会发现他们实际上在重复ID #content
。在我尝试的第一个视频中,加载评论部分后,document.querySelectorAll("#content")
实际上返回了大约20个元素。这不符合标准,W3's HTML Validator实际上会告诉您这是无效的HTML。但是,浏览器仍然允许这样做,而不是直接拒绝或修改HTML。
如果您的网站重复使用#divContentList
,则您的声明将从所有元素中返回所有article元素;而您的同事只会返回嵌套在找到的#divContentList
的 first 实例中的文章。这可以解释为什么您的同事通常看起来更快(请参阅下文)。就像大多数人已经指出的那样,在所有浏览器中用querySelector
替换他的第一个getElementById
可能会更快。
除此以外,我同意以下一般想法:“如果您想了解某件产品的性能,只需对其进行测量即可。”但要谨慎构造测试。 Here's an example where the JS engine optimized out the actual test case。我的建议总是在您的实际用例范围内进行测试。有很多话题谈论element.querySelector
can actually be slower than document.querySelector
的方式;但是,从最近的简短测试来看,我无法复制它。
在此页面本身上使用#sidebar
和.question-hyperlink
之类的ID /类,在所有情况下document.querySelector('<ID>').querySelectorAll('<CLASS>');
都胜过document.querySelectorAll('<ID> <CLASS>');
。
但是,我觉得这很关键,差异从未超过10%到20%。在某个时候,问题变成了“可读性/可写性与性能之间的权衡是否值得”。如果您只执行一次此语句一两次,则差异可能以微秒为单位。对于一般用例,您的原始陈述或同事的陈述都可以。
最后一点,
我不认为他的解决方案在速度性能上是最好的,它会搜索元素两次
如果您想读书,可以研究一下浏览器实际上如何实现这些网页查找方法。查看Firefox的源代码,您会发现“ getElementById”使用哈希表查找,这几乎可以瞬间找到结果。不同供应商的实现方式会有所不同,这就是为什么在许多不同的浏览器上测试站点很重要的原因。