sass 会损害性能吗?

Posted

技术标签:

【中文标题】sass 会损害性能吗?【英文标题】:Does sass harm performance? 【发布时间】:2011-10-13 03:13:10 【问题描述】:

我一直在自学。阅读this:

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

例如:

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 代码。 SASS/SCSS 允许人们轻松地指定需要“长手”CSS 的事物(尤其是嵌套)。虽然嵌套可能并不总是应用给定 CSS 的“正确方法”(它可能对文档来说过于严格和脆弱),但 CSS 选择器可以非常有效地与网络浏览器匹配。话虽这么说:我不会担心它,除非有一个可证明的 CSS“太慢”的测试用例。 【参考方案1】:

您必须在可维护性(嵌套使您更容易在样式表中找到自己的方式)和渲染性能之间找到折衷。

根据经验,您应该尝试将自己限制在三层嵌套中,如果没有必要,您应该避免嵌套 ID。

不过,我认为嵌套过多并不是最大的问题。当我意识到 mixins 的强大功能后,我就经常使用它们。

例如,这是我经常使用的按钮 mixin:

@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 directive 继承选择器。

如果您为 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 按钮的所有用法聚合到一个带有逗号分隔选择器的规则中:

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

最后,简单地使用 Sass 会影响您的 CSS 性能。然而,如果使用得当,它是可维护的,这要归功于结构良好且 DRY 的代码,它可以正确分离标记和样式(仅限语义类),并允许编写智能和高性能的 CSS 代码。

【讨论】:

我知道这个答案已经过去了 1.5 年,但我想知道......您多次提到性能,因为它适用于 CSS。 SASS/SCSS 将嵌套转换为性能不佳的 CSS 或文件太大的方式是否存在真正的问题? 好吧,there are studies 说优化选择器性能时不会产生太大影响。也许对于像 Chrome 这样的现代浏览器来说这并不重要。但是,如果您认为在较旧的 IE 浏览器或浏览器速度较慢且连接不良的手机上,选择器性能和 CSS 文件大小确实很重要。 另外,如果你考虑一个最终用户的性能图表,你可能有 500ms 的应用服务器时间、500ms 的网络时间、500ms 的浏览器 DOM 处理和 2000ms 的浏览器页面渲染时间。很多人会说 500 毫秒的应用服务器时间还不够好(不仅是因为缩放问题),但在浏览器中花费了 2.5 秒的时间 - 相当有可能减少! 询问优化的唯一答案是“使用分析器”。所有现代(包括移动)浏览器都有 CSS 分析器。使用它们,并根据这些结果指导您的优化。【参考方案2】:

SASS 只是一种编译成 CSS 的语言。如果您担心 SASS 在浏览器中的运行性能,那么 SASS 不会参与进来——它将被编译并作为常规 CSS 提供给浏览器。


根据您对 SASS 的使用情况,我可以提出以下几点建议:

    您没有必须嵌套所有内容。

在 SASS 中相互嵌套规则的能力是一种语言特性,但如果这样做没有意义,则不必这样做。


就您的一般 CSS 用法而言:

    如果嵌套过于严重/笨拙,请考虑在合理的情况下使用类。 当需要使用 DOM 元素的层次结构时,请考虑使用 [child 组合器]:.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,这样更易​​于维护和重用。

【讨论】:

对。但我认为问题在于这样一个事实,即 SASS 确实 倾向于生成比没有它时编写的更冗长的 CSS,仅仅是因为它更容易做到。有了这个假设——那么,“更深”的选择器有什么性能影响(如果有的话)?例如。浏览器如何有效地匹配它们?什么是 CSS 性能注意事项? 我链接到的文章回答了这个问题。长选择器被认为是慢的。我对在没有长嵌套选择器的情况下编译 sass 的方法更感兴趣。 #id1 #id2 看起来很奇怪,不应该嵌套(尽管将它们用于不同页面包含的边缘情况使得这更难识别)。我在问:这种性能影响严重吗?或者:有没有办法用 sass 做得更好?嵌套的重点是可读性。如果我放弃嵌套以使选择器更好。这是高级 css 语言中不太好的功能。 如果您在 SASS 中嵌套规则只是为了便于阅读,那么您就是在滥用语言功能。只有在以下情况下,您才应该嵌套规则:(a) 父级是您页面上严格且特定的上下文,并且 (b) 子级规则依赖于父级的上下文。如果您的嵌套子规则并非绝对需要父规则才能工作,请不要嵌套规则。

以上是关于sass 会损害性能吗?的主要内容,如果未能解决你的问题,请参考以下文章

在宏中过度使用会损害性能吗?

屏幕保护程序会损害 CUDA 性能吗?

更多的 HTML 属性或值会损害 Angular 的性能吗?

jQuery Mobile 在多大的 DOM 大小时会开始变得迟缓?添加数千个 LI 会损害性能吗?

为啥 arguments.callee 会损害性能?

为啥子查询中的 distinct on 会损害 PostgreSQL 的性能?