Sass会影响性能吗?

11

我一直在自学。阅读这篇文章

引擎从右到左评估每个规则,从最右边的选择器(称为“键”)开始,通过每个选择器移动,直到找到匹配项或放弃该规则。 (“选择器”是应用该规则的文档元素。)

例如:

ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...]

现在,以下是我从 SASS 获取的一些示例代码:

#content #blog {
  /* ... */
}
/* line 85, ../sass/screen.scss */
#content #flickr {
  /* ... */
}

#content #flickr div p {
  /* ... */
}

这看起来有点尴尬...我做错了什么吗?这是我和Sass之间的沟通问题吗?我们失去了什么吗?

编辑: 一些SCSS代码:

#flickr {
    @include columns(5,8);
    background: url('../img/ipadbg.png') no-repeat;

    #ipod-gloss {
        z-index: 999;
        position: relative;
    }

    div {
        margin-top: -80px;
        margin-right: 20px;

        h2 {
            color: $white;
            font-size: 24px;
        }

        p {
            margin-top: 40px;
        }
    }
}

额外加分!: 文章中提到浏览器(至少 Firefox)从右向左搜索选择器。我不明白这为什么是一种更有效的方法。有什么线索吗?


我看不到你的Sass/SCSS代码。 - BoltClock
1
SASS/SCSS可以轻松指定需要“长手”CSS才能实现的东西(特别是嵌套)。虽然嵌套不一定总是应用给定CSS的“正确方式”(它可能对文档过于严格和脆弱),但CSS选择器可以与Web浏览器非常有效地匹配。也就是说:除非有证明CSS“太慢”的可靠测试案例,否则不必担心它。 - user166390
2个回答

16

在样式表中,你需要在可维护性和渲染性能之间找到平衡点(通过嵌套可以更轻松地在样式表中找到相应的位置)。

一个经验法则是,尽量限制嵌套层数为三级,并避免在不必要的情况下嵌套ID选择器。

然而,我认为过度嵌套并不是最大的问题。一旦我意识到混合宏的威力,我就经常使用它们。

例如,这是我经常使用的按钮混合宏:

@mixin small-button($active-color: $active-color, $hover-color: $button-hover-color, $shadow: true)
  display: inline-block
  padding: 4px 10px
  margin:
    right: 10px
    bottom: 10px
  border: none
  background-color: $button-color
  color: $font-color-inv
  +sans-serif-font(9px, 700)
  text-align: center
  text-transform: uppercase
  cursor: pointer
  @if $shadow
    +light-shadow
  &:hover
    text-decoration: none
    background-color: $hover-color
  &:last-child
    margin-right: 0
  a
    color: $font-color-inv
    &, &:hover
      text-decoration: none
  &.disabled
    +opacity(0.75)
    &:hover
      background-color: $button-color
  &.active
    background-color: $active-color
    &.disabled:hover
      background-color: $active-color

你看,这是很多代码。在页面上应用这种mixin会导致生成一个大的CSS文件,需要更长时间来解释。

在传统的CSS方式中,你需要给每个按钮元素添加类,例如.small-button。但这种方法会在你的标记中添加不语义化的类。

Sass提供了一种解决方案:通过@extend指令实现选择器继承。

如果你为mixin的参数设置默认值,那么你还可以提供一个简单的类,使用带有默认值的mixin:

// Use this mixin via @extend if you are fine with the parameter defaults
.small-button
  +small-button

然后你只需要在不同的情境下从这个类继承:

#admin-interface
  input[type=submit]
    @extend .small-button

生成的 CSS 语句将所有使用 .small button 的规则聚合成一个规则,并用逗号分隔选择器:

.small-button, #admin-interface input[type=submit] {
  display: inline-block;
  ...
}

总之,使用 Sass 的时候需要注意一些问题,否则会影响 CSS 的性能。但是当你正确地使用 Sass 时,它能够让你的代码结构清晰、DRY,有助于标记和样式的分离(只使用语义化的类名),并且允许编写智能且高效的 CSS 代码。


我知道这个回答已经有1.5年了,但我想知道...你多次提到性能,因为它适用于CSS。SASS/SCSS将嵌套转换为性能不佳的CSS或文件大小过大,这种情况是否真的存在问题? - ZenMaster
有研究表明,优化选择器性能对于现代浏览器(如Chrome)可能没有太大影响。但是,如果考虑到旧版IE浏览器或具有较慢浏览器和差连接的移动电话,则选择器性能和CSS文件大小都很重要。 - crispy
此外,如果您考虑一个终端用户的性能图表,您可能会发现500毫秒的应用服务器时间,500毫秒的网络时间,500毫秒的浏览器DOM处理时间和2000毫秒的浏览器页面渲染时间。许多人会说500毫秒的应用服务器时间不够好(不仅因为扩展问题),但在浏览器中花费了2.5秒的时间 - 有相当大的潜力可以削减! - crispy
1
关于优化的唯一答案是“使用分析器”。现代浏览器(包括移动浏览器)都有 CSS 分析器。使用它们,并根据结果指导您的优化。 - David Souther

6
SASS只是一种编译成CSS的语言。如果您关心SASS在浏览器中的运行性能,那么SASS不会涉及到这个问题——它将被编译并作为常规CSS提供给浏览器。
从我对您对SASS使用的看法来看,我可以提出几点建议:
1. 您不必嵌套所有内容。 在SASS中嵌套规则的能力是一种语言特性,但如果没有必要,您不必这样做。
就一般的CSS用法而言:
1. 如果嵌套过于复杂或难以处理,请考虑在有意义的地方使用类。 2. 当需要使用DOM元素的层次结构时,请考虑使用[子组合器]:.foo > .bar
ID应该是唯一的,因此应始终仅引用单个元素。大多数情况下,它们可以成为CSS规则本身——例如,#content #flickr将变为#flickr,浏览器将优化查找单个ID。唯一需要像#id1 #id2这样的东西是如果#id2需要在不同页面的不同上下文中出现。
如果您的选择器包含诸如#id div p之类的内容,则div要么是多余的,要么是为特定目的服务的。
- 如果它是多余的,请将规则更改为#id p,这将选择作为#id的后代出现的任何<p>。 - 如果它有特定的用途,请考虑使用描述其用途的类名对<div>进行分类——例如<div class="photos-list">。然后,您的CSS可以变成.photos-list p,这样更易于维护和重用。

1
没错。但我认为问题的核心在于SASS会比没有使用它时生成更冗长的CSS,因为使用它更容易。基于这个前提,那么“深层次”的选择器有什么性能影响(如果有的话)?例如,浏览器如何高效地匹配它们?CSS的性能考虑有哪些? - user166390
1
我链接的文章已经回答了这个问题。长选择器被认为是慢的。我更感兴趣的是编译sass而不使用长嵌套选择器的方法。#id1 #id2看起来很奇怪,不应该嵌套(尽管在不同页面包含的边缘情况下,这使得它更难以识别)。我的问题是:这会对性能产生严重影响吗?或者:有没有一种更好的使用sass的方法?嵌套的整个目的是可读性...如果我放弃嵌套以使选择器更好...那就是高级css语言中少了一个好特性。 - CamelCamelCamel
5
如果你只是为了可读性而在SASS中嵌套规则,那么你就误用了这个语言特性。只有在以下情况下才应该嵌套规则:(a) 父元素是页面上严格和特定的上下文环境,并且 (b) 子规则在父元素上下文中具有相关性。如果你的嵌套子规则并不绝对需要父元素才能工作,就不要嵌套规则。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接