197

我讨厌它们,它违背了 CSS 的级联特性,如果你不小心使用它们,你最终会陷入添加更多!important.

但我想知道它们对性能有害吗?

编辑
从(快速)回复中,我可以得出结论,它不会对性能产生(显着)影响。但很高兴知道,即使它只是作为劝阻他人的额外论据;)。

EDIT 2
BoltClock 指出,如果有 2 个!important声明,规范会选择最具体的一个。

4

9 回答 9

271

它不应该对性能产生任何明显的影响。看到Firefox 的 CSS 解析器,/source/layout/style/nsCSSDataBlock.cpp#572我认为这是相关的例程,处理CSS 规则的覆盖

这似乎只是对“重要”的简单检查。

  if (aIsImportant) {
    if (!HasImportantBit(aPropID))
      changed = PR_TRUE;
    SetImportantBit(aPropID);
  } else {
    // ...
  }

另外,评论在source/layout/style/nsCSSDataBlock.h#219

    /**
     * Transfer the state for |aPropID| (which may be a shorthand)
     * from |aFromBlock| to this block.  The property being transferred
     * is !important if |aIsImportant| is true, and should replace an
     * existing !important property regardless of its own importance
     * if |aOverrideImportant| is true.
     * 
     * ...
     */

  1. Firefox 使用手动编写的自顶向下解析器。在这两种情况下,每个 CSS 文件都被解析为一个 StyleSheet 对象,每个对象都包含 CSS 规则。

  2. Firefox 然后创建包含最终值的样式上下文树(在以正确的顺序应用所有规则之后)

CSS 解析器 Firefox

来自:http://taligarsiel.com/Projects/howbrowserswork1.htm#CSS_parsing

现在,您可以很容易地看到,在使用上述对象模型的情况下,解析器可以!important轻松地标记受其影响的规则,而无需太多后续成本。性能下降并不是反对!important.

但是,可维护性确实会受到影响(如其他答案所述),这可能是您反对它们的唯一论据。

于 2012-12-06T15:28:40.237 回答
114

我不认为这!important在浏览器匹配规则的速度方面本质上是坏的(它不构成选择器的一部分,只是声明的一部分)

但是,正如已经说过的,它会降低代码的可维护性,因此可能会由于未来的变化而导致代码不必要地增长。的使用!important也可能会降低开发人员的性能。

如果你真的很挑剔,你也可以说!important在你的 CSS 文件中增加了 11 个额外的字节,这并不算多,但我想如果你!important的样式表中有相当多的 s,它可能会加起来。

只是我的想法,不幸的是我找不到任何关于如何!important影响性能的基准。

于 2012-12-06T12:42:59.183 回答
59

!important有它的位置。相信我。它救了我很多次,而且通常作为一种短期解决方案更有用,然后才能找到解决问题的更长更优雅的方法。

然而,像大多数事情一样,它被滥用了,但不必担心“性能”。我敢打赌,一个小的 1x1 GIF 在网页上比 !important 对性能的影响更大。

如果您想优化您的页面,还有更多!important路线可供选择 ;) ;)

于 2012-12-06T12:45:23.977 回答
32

幕后发生的事情是,当你的 CSS 被处理时,浏览器读取它,遇到一个!important属性,然后浏览器返回应用由!important. 这个额外的过程可能看起来像是一个额外的小步骤,但如果你要处理许多请求,那么你的性能就会受到影响。(来源)

在你的 CSS 中使用 !important 通常意味着开发人员自恋和自私或懒惰。尊重即将到来的开发者...

开发者在使用时的思考!important

  1. 我的摇摆 CSS 不工作... grrrr。
  2. 我现在该怎么办??
  3. 然后!important是的......现在它工作正常。

!important然而,仅仅因为我们没有很好地管理 CSS ,它并不是一个好的使用方法。它产生了很多设计问题——比性能问题更糟糕——但它也迫使我们使用许多额外的代码行,因为我们正在覆盖其他属性,!important并且我们的 CSS 变得混乱无用的代码。我们应该做的是首先很好地管理 CSS,而不是让属性相互覆盖。

我们可以使用!important. 但是要谨慎使用它,并且只有在没有其他出路的情况下才使用它。

在此处输入图像描述

于 2012-12-06T14:04:11.593 回答
14

我同意你不使用它的观点,因为这是不好的做法,无论性能如何。仅基于这些理由,我会!important尽可能避免使用。

但在性能问题上:不,它不应该引起注意。它可能会产生一些影响,但它应该是如此之小,以至于您永远不会注意到它,也不应该担心它。

如果它的重要性足以引起注意,那么您的代码中可能会遇到更大的问题,而不仅仅是!important. 简单使用您正在使用的核心语言的正常语法元素永远不会成为性能问题。

让我用一个反问来回答你的问题;一个你可能没有考虑过的角度:你指的是哪个浏览器?

每个浏览器显然都有自己的渲染引擎,并有自己的优化。所以现在的问题变成了:每个浏览器的性能影响是什么?也许!important在一种浏览器中表现不佳,但在另一种浏览器中表现良好?也许在下一个版本中,情况会相反?

我想我的观点是,我们作为 Web 开发人员不应该考虑(或需要考虑)我们正在使用的语言的单个语法结构的性能影响。我们应该使用这些语法结构,因为它们是实现我们想要做的事情的正确方法,而不是因为它们的执行方式。

性能问题应与使用分析器一起提出,以分析系统中的关键点。首先解决真正让你慢下来的事情。在你深入到单个 CSS 结构的层次之前,几乎可以肯定你要解决的问题要大得多。

于 2012-12-06T13:19:53.357 回答
7

它不会显着影响性能。但是,它确实会降低代码的可维护性,因此从长远来看可能会降低性能。

于 2012-12-06T12:38:47.197 回答
7

之前不得不使用!important过几次,我个人注意到使用它时没有明显的性能下降。

作为注释,请参阅此堆栈问题的答案,因为您可能想使用!important.

另外我会提到一些其他人都没有提到的东西。!important是重写内联 css 的唯一方法,而不是编写一个 javascript 函数(即使只有一点点也会影响你的性能)。因此,如果您需要覆盖内联 css,它实际上可以为您节省一些性能时间。

于 2012-12-06T15:34:00.227 回答
6

嗯... !important 还是 !!important?

让我们一步一步来:

  1. 解析器必须检查每个属性的 !important,无论您是否使用它 - 所以这里的性能差异为 0
  2. 覆盖属性时,解析器必须检查被覆盖的属性是否是 !important - 所以这里的性能差异再次为 0
  3. 如果被覆盖的属性是 !!important,它必须覆盖属性 - 性能命中为 -1,因为不使用 !important
  4. 如果被覆盖的属性是 !important,它会跳过覆盖属性 - 使用 !important 的性能提升 +1
  5. 如果新属性是 !important,则无论被覆盖的属性是 !important 还是 !!important,解析都必须覆盖它 - 性能差异再次为 0

所以我猜 !important 实际上有更好的性能,因为它可以帮助解析器跳过许多它不会跳过的属性。

正如@ryan 在下面提到的那样,覆盖内联css并避免使用javascript的唯一方法......所以另一种避免不必要的性能影响的方法

嗯...原来 !important 很重要

并且,

  • 使用 !important 为开发人员节省了大量时间
  • 有时可以使您免于重新设计整个 CSS
  • 有时 html 或父 css 文件不在您的控制范围内,因此它可以挽救您的生命
  • 显然可以防止 !important 元素被其他 !!important 元素意外覆盖
  • 有时浏览器只是没有选择正确的属性,没有在选择器中过于具体,所以使用 !important 真的变得很重要,并且可以让你免于在你的 CSS 中编写大量特定的 CSS 选择器。所以我想即使您使用更多字节来编写!important,它也可以在其他地方为您节省字节。我们都知道,css 选择器会变得混乱。

所以我想使用 !important 可以让开发人员开心,我认为这非常重要:D

于 2012-12-06T22:22:04.227 回答
4

我无法预见!important阻碍性能,无论如何都不是。但是,如果您的 CSS 中充满了!important,则表明您已经过度限定选择器并且过于具体,并且您已经用完了父母或限定符来增加特异性。因此,您的 CSS 将变得臃肿(这影响性能)并且难以维护。

重要的 CSS 规则模因

如果您想编写高效的 CSS,那么您只想尽可能具体并编写模块化 CSS。建议不要使用 ID(带有哈希)、链接选择器或限定选择器。

在 CSS 中以前缀为前缀的 ID#非常具体,以至于255 个类不会覆盖一个 id(由@Faust 调整)。ID 也有更深层次的路由问题,它们必须是唯一的,这意味着您不能将它们重复用于重复样式,因此您最终会编写带有重复样式的线性 css。这样做的影响会因项目而异,具体取决于规模,但可维护性将受到极大影响,在极端情况下,性能也会受到影响。

如何在没有!important、链接、限定或 ID 的情况下添加特异性(即#

HTML

<div class="eg1-foo">
    <p class="eg1-bar">foobar</p>
</div>
<div id="eg2-foo">
    <p id="eg2-bar">foobar</p>
</div>
<div class="eg3-foo">
    <p class="eg3-foo">foobar</p>
</div>

CSS

.eg1-foo {
    color: blue;
}
.eg1-bar {
    color: red;
}
[id='eg2-foo'] {
    color: blue;
}
[id='eg2-bar'] {
    color: red;
}
.eg3-foo {
    color: blue;
}
.eg3-foo.eg3-foo {
    color: red;
}

JSFiddle

好的,那它是如何工作的?

第一个和第二个示例的工作方式相同,第一个实际上是一个类,第二个是属性选择器。类和属性选择器具有相同的特性。.eg1/2-bar不会继承其颜色,.eg1/2-foo因为它有自己的规则。

第三个示例看起来像限定或链接选择器,但两者都不是。链接是当您在选择器前面加上父母、祖先等时;这增加了特异性。限定是类似的,但你定义了选择器应用到的元素。排位赛:ul.class和链接:ul .class

我不确定你会如何称呼这种技术,但这种行为是故意的,并且由 W3C 记录

允许重复出现相同的简单选择器并且确实增加了特异性。

当两个规则之间的特异性相同时会发生什么?

正如@BoltClock 指出的那样,如果有多个 !important 声明,那么规范规定最具体的声明应该优先。

在下面的示例中,两者.foo.bar具有相同的特性,因此行为回退到 CSS 的级联性质,其中 CSS 中声明的最后一条规则声明优先级,即.foo.

HTML

<div>
    <p class="foo bar">foobar</p>
</div>

CSS

.bar {
    color: blue !important;
}
.foo {
    color: red !important;
}

JSFiddle

于 2014-07-24T20:56:02.080 回答