【问题标题】:CSS selector performance - pseudo selectorsCSS 选择器性能 - 伪选择器
【发布时间】:2014-02-03 07:51:28
【问题描述】:

CSS 选择器从右到左解析,然后显示。

考虑到这一点,基于此代码:

<a href="#" class="myImage">
    <img>
</a>

哪个性能更好?:

.myImage img 

.myImage img:only-child

:only-child 是否有助于选择器选择的特异性?因此,与其最初匹配文档中的所有&lt;img&gt;,然后寻找父类,不如只匹配作为唯一子类的&lt;img&gt;(从而减少选择池)?

参考阅读:http://csswizardry.com/2011/09/writing-efficient-css-selectors/

编辑

找到进一步阅读:

关于 CSS3 选择器的可悲事实是,它们真的不应该 如果您关心页面性能,请完全使用。装饰你的标记 具有类和 id 并仅在那些上进行匹配,同时避免所有 使用兄弟、后代和子选择器实际上会产生一个 页面在所有浏览器中的性能都显着提高。

-David Hyatt(Safari 和 WebKit 的架构师,也曾在 Mozilla、Camino 和 Firefox 上工作) 来源:http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

【问题讨论】:

  • 你正在用这些选择器做两件不同的事情。首先,您必须尝试实现一些相关的东西才能进行比较。我相信,如果您尝试在 img 的唯一孩子上应用样式,那么显然这将是更好的选择,因为 img 会将样式应用于 .myImg 类中的所有 img,这是您不做的事情不想。
  • " :only-child 是否有助于选择器选择的特异性?"嗯,是的……这就是重点。

标签: performance css css-selectors pseudo-class


【解决方案1】:

好的,所以这完全取决于用例。我要做的是处理案件。

第 1 点 - 关于给定示例


案例A

说你的代码很简单:

<a href="#" class="myImage">
    <img>
</a>

在这种情况下,.myImage img.myImage img:only-child 将具有基本相同的性能命中。原因如下:

CSS 性能命中源于必须为框设置样式或重新设置样式。 CSS 所做的是影响你的图形处理器,而不是 CPU,所以我们只关心视觉更新。并且使用重复属性再次设置样式确实会导致重绘(我的意思是稍后应用的重复属性,这通常是选择器导致的)。

通常,.myImage img 会在.myImage 中设置所有&lt;img&gt;s 的样式。虽然使用 only-child 选择器可能不会全部设置样式(显然)。

但在这个例子中,.myImage img.myImage img:only-child 会做相同的事情,因为它们都会在同一个盒子上导致 1 次绘制/重绘。


案例 B

但假设我们有:

<a href="#" class="myImage">
    <img>
    <img>
</a>

不过,我们有不同的故事。

在这个例子中,only-child 根本不起作用,因为&lt;img&gt; 不是唯一的孩子。


案例 C

最后,假设你有这个,但你只想在下面设置样式:

<a href="#" class="myImage">
    <img>
</a>
<div class="myImage>
    <img>
    <img>
</div>

在这种情况下,使用 only-child 选择器会显着提高性能,因为您只需设置一个元素的样式,而不是三个。


结论和要点

基本上,记住一些事情。

  • CSS 选择器可以帮助您编写代码,因为您可以添加更少的 ID 和类,但是,它们几乎总是比使用所有 ID 和类效率低,因为使用选择器会导致额外的重绘。 (因为您不可避免地会使用一些选择器为多个元素设置样式,然后使用 ID 或类重新设置其他元素的样式,从而导致不必要的重绘)

  • 如果 .class 只有一个孩子,only-child 不会比 .class child 快。

  • 从技术上讲,您要比较的是两个完全不同的东西,用于不同的目的。

结论

最后回答你的问题。在您显示的示例中,两者都没有比另一个更有效,因为它们会导致相同的重绘。

然而,作为

:only-child 是否有助于选择器选择的特异性?”

goes:是的,这就是选择器的重点。见:http://www.w3schools.com/cssref/sel_only-child.asp

来源: 我是 Mozilla Thunderbird 和 Mozilla 项目的重要志愿者开发人员,并在 CSS 领域工作。

仅供参考

这当然有奇怪的例外,但我不会在这里讨论它们,因为我认为你的确切问题没有给出一个很好的例子。

第 2 点 - 关于查找选择器的速度

我故意试图强调这是导致 CSS 性能命中的原因,而不是找到选择器。 然而,我之所以这么说并不是因为找到选择器不需要时间,而是因为它的时间与绘制所花费的时间相比是微不足道的。也就是说,如果您确实有 5,000 个&lt;div&gt;s 或其他东西,并尝试使用伪选择器设置一些样式,那么它肯定会比使用 CSS 类和 ID 长一点。

同样,在您的示例中,它没有任何区别,因为它无论如何都会查看每个元素。为什么 only-child 在性能方面很有帮助是因为它会在找到多个子元素后停止搜索某个元素,而简单地执行 class child 则不会。

伪选择器的问题是它们通常需要大量额外的搜索,而且它发生在 ID、类等之后。

您提供的链接实际上非常有用,我很惊讶他们没有回答您的问题。

我应该指出的一件事是,许多被认为很慢的选择器现在可能得到了极大的改进。见:http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/

请记住,选择器性能仅在非常大的网站上很重要。

【讨论】:

  • "使用重复属性再次设置样式确实会导致重绘。"您是指影响同一元素的两条规则吗?如果是这样,那么每个元素的级联分辨率肯定会阻止这种情况吗?还是我太天真了?
  • @BoltClock:不,这是正确的。我应该更具体。我的理解是每个元素级联仅适用于正常的 CSS 规则。但是,通过 JS 进行更改会导致重绘,类似的技术可能会面临同样的问题。我真正要指出的是,CSS 性能几乎完全取决于它必须绘制多少,而不是它找到元素的速度。
  • 感谢您的深入回答。这些链接基本上回答了我的问题,但我将其留待讨论。
  • @Josiah:啊,我明白你的意思了。
猜你喜欢
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 2017-06-20
相关资源
最近更新 更多