【问题标题】:What selector is more efficient什么选择器效率更高
【发布时间】:2019-06-12 18:34:50
【问题描述】:

我正在使用 jQuery,我想知道哪个选择器更快,但我不知道从哪里开始测试它。我知道最有效的选择器(最快)是使用像$("#xxx") 这样的id。

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

【问题讨论】:

  • 我不认为这是重复的。这是一个简单的问题,即选择器或方法哪个更快,而不是哪个更快。

标签: jquery selector


【解决方案1】:

一般来说,选择器按以下效率顺序排列(从最高效率到最低效率):

  • 身份证
  • 标签名称
  • 子女关系 (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 搜索有关的实际性能问题,那么最好开始测试它那类的东西。 (尽管如此,很多时候你会看到缓存和重用以前的选择比微调选择本身有更多的改进。)

使用常识,尽量让选择器简单明了,并在可能的情况下重复使用它们——但除非你看到真正的性能问题,否则可能不值得每毫秒都费劲。

【讨论】:

  • 哇非常清楚,尽管您的一些意见没有证据,但它们非常合乎逻辑,并且您提供的代码可以测试任何东西!出于某种原因,我在我的网站上使用了您的代码,[data-src]img[data-src] 快 8%(8% 不足以告诉我确定哪种情况更好,但我不确定我会使用[data-src]。跨度>
  • 我敢肯定,根据被搜索的特定 html(以及执行搜索的特定引擎),会有很多变化,是的。整个答案可能可以归结为“如有疑问,请运行测试”:)
【解决方案2】:

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

【讨论】:

  • 我认为选择器会先检查 attr,然后再检查类型。我以为它会从“从右到左”阅读。无论如何,如果你确定这一点,我非常感谢你!
  • 根据这个答案stackoverflow.com/questions/4262928/…方法比选择器快。
  • 如果是$("img .class[data-src]"),那么它将使用类选择器从右到左读取,然后是标签。但在这种情况下,我们只查看一个选择器。
猜你喜欢
  • 2023-03-03
  • 2011-11-07
  • 2012-04-04
  • 2011-07-03
  • 2016-11-07
  • 1970-01-01
  • 2011-04-18
  • 2013-04-05
  • 1970-01-01
相关资源
最近更新 更多