【问题标题】:Why doesn't querySelector('#id') map to document.getElementById('id')?为什么 querySelector('#id') 不映射到 document.getElementById('id')?
【发布时间】:2011-05-16 22:59:38
【问题描述】:

我最近对选择器的性能感兴趣,当传递一个简单的#id 时,当前实现选择器 API 的浏览器不使用 document.getElementById,这让我很烦恼。

性能损失是huge,因此库作者继续实施他们自己的解决方法。

有什么想法吗?

【问题讨论】:

  • 我没有查看这些浏览器的源代码,但你确定它们不直接映射吗?解析字符串并计算它是否只是一个直接的 id 将会有性能损失。
  • 伙计们,如果您单击问题中链接的 jsperf 测试,应该清楚的是,如果浏览器 尝试 将“#id”选择器分流到 @987654325 @分辨率,它正在做一个可怕的工作。它可能没有尝试。
  • @Gumbo — 好的,现在我必须删除引用该部分代码的答案!
  • @David Dorward:为什么?是您给出了为什么差异如此“巨大”的答案。

标签: javascript browser css-selectors selectors-api


【解决方案1】:

在上面发表评论后,我决定继续:

来自 Chromium 源中的 Node.cpp

if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) {
    Element* element = document()->getElementById(querySelectorList.first()->m_value);
    if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element))
        return element;
    return 0;
}

所以它确实映射到getElementById,只是解析字符串以查找选择器是一项昂贵的操作。

【讨论】:

  • 谢谢,大卫!我不知道在 Chromium 的源代码中查看哪里。
【解决方案2】:

太。性能损失是微不足道的......我真的怀疑你是否会每秒进行 100.000 次 id 查找,如果你这样做了,那么 QSA 性能实际上是你应该看的最后一件事。

至于为什么,添加额外的 if/else 可能会使 id 查找更高效,但其他 css 选择器会慢一点(仍然微不足道)。为什么要优化 QSA 来处理 id 查找,既然有专门的方法可以更快地做到这一点。

在任何情况下,浏览器都以速度为目标,而忽略此类内容会使整体性能图表看起来更好。在这场基准竞赛中,它几乎是每一毫秒,但对于开发人员来说......请现实一点,其他基准更为重要,QSA 性能应该不再是一个因素。

为了方便开发人员,它可以工作,它仍然非常快,以至于您在实际应用程序中都不会注意到它(我挑战你告诉我它在哪里是视觉上引人注目的,同时仍然是一个理智的程序;o)。

【讨论】:

    【解决方案3】:

    也许是因为如果他们这样做了,他们将不得不添加一个检查以查看它是否是一个简单的 id 查询(无修饰符),这会减慢 每个 其他查询?进行测试可能不会对性能造成巨大影响,但很难为其他开发人员说话。

    我认为如果您担心它,您可以添加一个类似 getObByID 的函数来检查文档,getElementById,如果存在则使用它,否则使用选择器。当您可以轻松地自己完成时,开发人员可能不会觉得有必要添加这种类型的抽象,而是由开发人员记住使用它,并增加学习曲线。

    【讨论】:

      【解决方案4】:

      我在比较getElementById()querySelector(),发现有人已经做了performance comparisons and calculations

      看起来querySelector() 确实每次都赢了......而且相当大的数量

      【讨论】:

      • 我想你可能把它弄反了。
      猜你喜欢
      • 2011-10-23
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 2020-06-02
      • 2018-03-26
      • 2017-12-15
      • 2020-06-24
      • 1970-01-01
      相关资源
      最近更新 更多