子选择器和后代选择器在性能上有区别吗?
Is there a difference in performance between the child and descendant selectors?
我可以使用子组合器 >
或仅 space 来表示任何后代来编写 CSS 选择器。例如,我有这个 HTML 代码:
<span id='test'>
<a href="#">Hello</a>
</span>
我可以用以下两种方式编写我的 CSS 代码:
#test > a {
...
}
或
#test a {
...
}
关于性能,编写以下 CSS 代码的最佳方法是什么?
请注意,select或两者都不会为您提供相同的输出!在您的示例中,确实如此。
但是让我们检查下一个 HTML 代码,它包含两个 link。
<div id="test">
<p> lorum ipsum <a href="#">here</a> dolor </p>
<a href="#">read more</a>
</div>
正文之间有一个link,段落后有一个link,让用户阅读更多的文字。 (比如在新闻网站上)。
如果你使用
#test a {
...
}
那么你将 select 都 link。
如果你使用
#test > a {
...
}
它只会 select #test
的直系后代 link,即读 more-link !那是因为 >
是一个 child combinator。段落中的 link 不会被 select 编辑。
以下是向您展示差异的片段。
#test a {
color: red;
}
#test > a {
font-weight: bold;
font-size: 18px;
}
<div id="test">
<p>lorum ipsum <a href="#">here</a> dolor</p>
<a href="#">read more</a>
</div>
如您所见,第二个 CSS 规则只编辑了第一个子 <a>
元素("read more" link)。
现在,回到关于您所处情况的性能的问题:如果您同时使用 select 或在下一个 HTML 部分
<div id="test">
<a href="#">Hello</a>
</div>
这里的性能是一样的。
-- edit1: 对上面这句话的澄清--
当使用 selector 时,它会从右到左检查。在 this 情况下,正文中有一个 div,div 中有一个 link 元素,性能相同。这是因为当使用 #test > a
时,它会检查所有 link 以查看其父项是否具有 id="test"
。它不会进一步遍历树。
当使用 #test a
时,它会检查 link 元素(直到根)的所有父元素以查看它是否具有 id="test"
。由于在这种情况下,div 已经在第一次父检查时找到,因此不必进一步遍历树。
但在其他情况下,当 div 不是文档中的唯一元素时,它当然会有所不同。您不能在这里比较差异,因为如前所述,结果不同。除非你保证给定的div下没有second-levellink。那么,使用>
当然更快。
-- 结束编辑--
但是,如果此人扩展了上述 div 的内容,he/she 可能会面临意想不到的 CSS 样式。
但要了解整体性能,这实际上取决于您想要通过 CSS(设置所有 link 还是仅设置第一级?)和 DOM 实现的目标div#tree
中的树(树的深度?)。
Browsers parse selectors from right to left.
然后,如果您使用 #test > a
,对于页面中的每个 a
元素,浏览器会检查其父元素是否具有 id="test"
.
但是如果您使用 #test a
,对于页面中的每个 a
元素,浏览器会检查其某些祖先是否具有 id="test"
。文档中不应该有很多这样的元素,所以浏览器可能必须检查每个 a
.
的所有祖先
我没有做任何测试,但我预计检查所有祖先比只检查父要慢。
所以可能 #test > a
更快。
我可以使用子组合器 >
或仅 space 来表示任何后代来编写 CSS 选择器。例如,我有这个 HTML 代码:
<span id='test'>
<a href="#">Hello</a>
</span>
我可以用以下两种方式编写我的 CSS 代码:
#test > a {
...
}
或
#test a {
...
}
关于性能,编写以下 CSS 代码的最佳方法是什么?
请注意,select或两者都不会为您提供相同的输出!在您的示例中,确实如此。
但是让我们检查下一个 HTML 代码,它包含两个 link。
<div id="test">
<p> lorum ipsum <a href="#">here</a> dolor </p>
<a href="#">read more</a>
</div>
正文之间有一个link,段落后有一个link,让用户阅读更多的文字。 (比如在新闻网站上)。
如果你使用
#test a {
...
}
那么你将 select 都 link。
如果你使用
#test > a {
...
}
它只会 select #test
的直系后代 link,即读 more-link !那是因为 >
是一个 child combinator。段落中的 link 不会被 select 编辑。
以下是向您展示差异的片段。
#test a {
color: red;
}
#test > a {
font-weight: bold;
font-size: 18px;
}
<div id="test">
<p>lorum ipsum <a href="#">here</a> dolor</p>
<a href="#">read more</a>
</div>
如您所见,第二个 CSS 规则只编辑了第一个子 <a>
元素("read more" link)。
现在,回到关于您所处情况的性能的问题:如果您同时使用 select 或在下一个 HTML 部分
<div id="test">
<a href="#">Hello</a>
</div>
这里的性能是一样的。
-- edit1: 对上面这句话的澄清--
当使用 selector 时,它会从右到左检查。在 this 情况下,正文中有一个 div,div 中有一个 link 元素,性能相同。这是因为当使用 #test > a
时,它会检查所有 link 以查看其父项是否具有 id="test"
。它不会进一步遍历树。
当使用 #test a
时,它会检查 link 元素(直到根)的所有父元素以查看它是否具有 id="test"
。由于在这种情况下,div 已经在第一次父检查时找到,因此不必进一步遍历树。
但在其他情况下,当 div 不是文档中的唯一元素时,它当然会有所不同。您不能在这里比较差异,因为如前所述,结果不同。除非你保证给定的div下没有second-levellink。那么,使用>
当然更快。
-- 结束编辑--
但是,如果此人扩展了上述 div 的内容,he/she 可能会面临意想不到的 CSS 样式。
但要了解整体性能,这实际上取决于您想要通过 CSS(设置所有 link 还是仅设置第一级?)和 DOM 实现的目标div#tree
中的树(树的深度?)。
Browsers parse selectors from right to left.
然后,如果您使用 #test > a
,对于页面中的每个 a
元素,浏览器会检查其父元素是否具有 id="test"
.
但是如果您使用 #test a
,对于页面中的每个 a
元素,浏览器会检查其某些祖先是否具有 id="test"
。文档中不应该有很多这样的元素,所以浏览器可能必须检查每个 a
.
我没有做任何测试,但我预计检查所有祖先比只检查父要慢。
所以可能 #test > a
更快。