孩子和后代选择者之间的表现有差异吗?

时间:2016-01-09 15:42:38

标签: css performance css-selectors micro-optimization

我可以使用子组合子>编写CSS选择器,或者只是指示任何后代的空格。例如,我有这个HTML代码:

<span id='test'>
    <a href="#">Hello</a>
</span>

我可以通过以下两种方式编写CSS代码:

#test > a {
    ...
}

#test a {
    ...
}

关于性能,编写以下CSS代码的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

Browsers parse selectors from right to left

然后,如果您对页面中的每个#test > a元素使用a,则浏览器会检查其父级是否有id="test"

但如果您使用#test a,则对于您网页中的每个a元素,浏览器会检查其某些祖先是否有id="test"。文档中应该没有很多元素,因此浏览器可能必须检查每个a的所有祖先。

我还没有做过任何测试,但我希望检查所有祖先比只检查父级要慢。

所以#test > a可能更快。

答案 1 :(得分:3)

请注意,两个选择器都没有给你相同的输出!在你的例子中,确实如此。

但是,让我们检查下一个包含两个链接的HTML代码。

<div id="test">
    <p> lorum ipsum <a href="#">here</a> dolor </p>
    <a href="#">read more</a>
</div>

文本与段落后面的链接之间存在链接,以允许用户阅读更多文本。 (比如在新闻网站上)。

如果您使用

#test a {
    ...
}

然后您将选择两个链接。

如果您使用

#test > a {
    ...
}

它只会选择#test的直接后代链接,这是读取更多链接!这是因为>child combinator。该段落中的链接不会被选中。

以下是一个显示差异的片段。

&#13;
&#13;
#test a {
  color: red;
}
#test > a {
  font-weight: bold;
  font-size: 18px;
}
&#13;
<div id="test">
  <p>lorum ipsum <a href="#">here</a> dolor</p>
  <a href="#">read more</a>
</div>
&#13;
&#13;
&#13;

如您所见,第二个CSS规则仅编辑了第一个子<a>元素(&#34;阅读更多&#34;链接)。

现在,回到你关于你的情况下的表现的问题:如果你在下一个HTML部分使用两个选择器

<div id="test">
    <a href="#">Hello</a>
</div>

表现明智,它在这里也一样。

- edit1:澄清上述句子 -

使用选择器时,它从右到左进行检查。在 this 情况下,在body中有一个div,在div中有一个link元素,性能相同。这是因为在使用#test > a时,它会检查所有链接以查看其父级是否有id="test"。它不会进一步遍历树。

使用#test a时,它会检查链接元素的所有父项(直到根),看它是否有id="test"。由于在这种情况下已经在第一次父检查中找到了div,因此它不必进一步遍历树。

但在其他情况下,当div不是文档中唯一的元素时,它当然会产生影响。你无法比较这里的差异,因为如前所述,结果是不同的。除非您确保给定div下没有二级链接。然后,>的使用当然更快。

- 结束编辑 -

但是,如果此人扩展了上述div的内容,他/她可能会遇到意想不到的CSS样式。

但要了解整体性能,它真的取决于你想要通过CSS(样式所有链接或仅第一级?)和DOM树(树的深度?)在div#tree中实现的目标。