CSS 子选择器性能与类膨胀

Posted

技术标签:

【中文标题】CSS 子选择器性能与类膨胀【英文标题】:CSS child selector performance vs. class bloat 【发布时间】:2012-12-10 10:01:31 【问题描述】:

我正在努力学习编写更高效的 CSS,尤其是当我正在处理一个需要快速呈现的相当复杂的网站时。

我习惯在我的 html/CSS 中有很多这样的内容(主要是因为我喜欢可读性):

.spotlight 
.spotlight ul 
.spotlight ul li 
.spotlight ul li a color: #333;

<div class="spotlight">
  <ul>
    <li><a href="">link</a></li>
    <li><a href="">link</a></li>
    <li><a href="">link</a></li>
  </ul>
</div>

我现在了解到浏览器从右到左运行 CSS 规则匹配过程,这意味着上面最后一个 CSS 规则中的 &lt;a&gt; 元素将首先匹配页面上的每个链接,从而导致性能损失。

因此,据我所知,浏览器友好的解决方案将更具体,并使用,例如:

.spotlight 
.spotlight-link color: #333;

    <div class="spotlight">
      <ul>
        <li><a class="spotlight-link" href="">link</a></li>
        <li><a class="spotlight-link" href="">link</a></li>
        <li><a class="spotlight-link" href="">link</a></li>
      </ul>
    </div>

(假设我尽可能使用继承,但通常仍需要对树下的最后一个元素进行特定控制)

让我怀疑的是:在整个页面中的元素上打印类名所产生的所有额外 HTML 膨胀难道不会抵消避免嵌套 CSS 子选择器所带来的性能提升吗?我习惯于尝试编写更少的 HTML,而这种做法与它背道而驰。任何见解将不胜感激。

【问题讨论】:

通常避免后代选择器的原因(在实践中)不是性能,而是 CSS 范围/维护(很难在评论中真正解释)。浏览器解析 CSS 的速度非常快,我真的不会太担心。如果你真的很担心速度而不是维护,你可以使用单字符类名 @Wesley Murch:“通常避免后代选择器的原因(在实践中)不是性能,而是 CSS 范围/维护”不幸的是,that's not what they'd like to have you think... “在整个页面中的元素上打印类名称所产生的所有额外 HTML 膨胀难道不会抵消避免嵌套 CSS 子选择器所带来的性能提升吗?”确切地。为了客户端性能而膨胀所有 HTTP 请求确实没有意义。 郑重声明,Mozilla 的文章最初是为设计自己的 UI 设计的,其中客户端性能是可以理解的至高无上的。我无法忍受他们对某些选择器做出的所有歧视性概括。后代组合器已经存在了将近 20 年。如果 20 年后浏览器仍然无法快速匹配它们,那么有些事情是非常非常错误的。这很愚蠢。 我只是完全避免使用 javascript、CSS 和 HTML——它们对性能非常不利。哦,不要让我开始使用图像... 【参考方案1】:

你必须权衡它。向每个锚点添加一个类是荒谬的,HTML 中的额外膨胀将大大抵消节省的渲染时间(这将是蜜蜂腿的 1/10,000)。更不用说你的代码维护起来有多难了。

你只需要停止使用不必要的昂贵选择器,例如

.spotlight ul li a

可以写成

.spotlight a

如果您继续在 HTML 中的相同元素上指定单个类(如您的第二个示例),则最好使用标签选择器。

您还必须权衡您的时间与浏览器的时间。在每次加载页面时节省几纳秒的时间需要花费多少?老实说,这真的不值得。

此外,使您的 CSS 结构与您的 HTML 结构相匹配就否定了 CSS 的意义——如果 HTML 发生变化,您需要更改您的 CSS。所以你总是希望你的选择器尽可能不具体。

但这里没有正确或错误的答案。

【讨论】:

【参考方案2】:

我认为最好的权衡是使用子组合器&gt; 来处理重复多次的元素,并在事情开始变得过于嵌套时使用类。

Bending the Rules of BEM

考虑到我们的选择,我认为上述文章达到了完美的平衡。

使用 SCSS,现在应该是强制性的,我的导航菜单通常看起来像这样(这绝对是我会嵌套最多的东西):

.header__nav 
  > ul 
    > li 
      > a 
    
  

【讨论】:

以上是关于CSS 子选择器性能与类膨胀的主要内容,如果未能解决你的问题,请参考以下文章

20, CSS 定义选择器

使用 CSS 子选择器会更快吗?

css选择器的1.5 子选择器

css后代选择器和子选择器的区别

CSS相关问题

CSS系列之后代选择器子选择器和相邻兄弟选择器