哪种选择器更有效

时间:2019-01-18 13:21:49

标签: jquery selector

我正在使用jQuery,我想知道哪个选择器更快,但是我不知道从哪里开始测试它。我了解到,最高效的选择器(最快)正在使用$("#xxx")之类的ID。

但是$("img[data-src]")$("[data-src]")呢?什么是最有效的?我知道选择器是从右到左读取的,因此我应该假设从选择器中删除“ img”会使其更快?如果是这样,您是否知道我可以在页面上运行以检查1000次哪个选择器最快的代码?

2 个答案:

答案 0 :(得分:2)

img是一个更快的选择器,因为它只需要查看$("[data-src]")标记,而php可以查看DOM中具有该属性的每个元素。

答案 1 :(得分:1)

通常,选择器的效率顺序如下(从最高效率到最低效率):

  • ID
  • 班级
  • 标签名称
  • 孩子关系(foo > bar
  • 后代关系(foo bar
  • 属性(foo[bar="baz"]
  • 伪类(foo:hoverfoo:nth-child()

另一个要考虑的因素是CSS选择器基本上是树搜索,因此可以从树中修剪的越多越好。 #foo .bar是一个后代关系,但是如果包含#foo将会从搜索中排除很多HTML,那将使选择器更加有效。类似地,img[data-src]在理论上比[data-src]更快,因为需要检查其属性的元素集比较有限。

(我不确定这一点,但希望CSS规则不是 总是按照从右到左的严格顺序进行解释。例如#foo .bar会更有效如果从左到右解释:首先寻找ID元素,然后只需要测试其.bar的子元素,而不是搜索整个文档即可,我认为大多数这样的显着性能优化已内置在其中,所有浏览器引擎。)

在某些情况下,您可以将javascript方法替换为css规则,例如$('foo:nth-child(1)')$('foo').first()-在这种特定情况下,jQuery is faster虽然不能全部推广选择器(当然,因为它们没有对应的方法)。

如果有疑问,您可以通过循环运行选择(针对您的真实HTML)来对这类内容进行基准测试:

benchmark = function(selector) {
  var t1 = new Date();
  for (var i=0; i<100000; i++) {
      var x = $(selector);
  }
  var t2 = new Date();

  console.log(selector, t2-t1, "ms")
}

benchmark('[data-src="bar"]')
benchmark('img[data-src="bar"]')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div data-src="bar"></div>
  <img data-src="bar">
</div>

...的结果使我想到了要点:过早的优化。

在大多数情况下,对于大多数网页而言,这与实际情况差异不大。使用上面非常简单的HTML,选择器即使进行100,000次迭代也几乎没有任何区别。在10,000次迭代中,我什至没有获得更快的一致结果。

如果您使用的是相对较大的HTML树和复杂的选择器,并且开始看到怀疑与这些DOM搜索相关的实际性能问题,那么然后开始进行测试是个好主意那类的东西。 (尽管即便如此,缓存和重用以前的选择还是要比微调选择本身有更多的改进。)

运用常识,尝试使选择器简单明了,并在可能的情况下重用它们,但是除非您看到真正的性能问题,否则不值得花费每一毫秒的时间。