重要对性能有害吗?


192

我讨厌它们,它违背了CSS的层叠特性,如果您不小心使用它们,最终会陷入添加更多的循环!important

但是我想知道它们是否对性能不利?

编辑
从(快速)回复我可以断定它不会对性能产生(显著)的影响。但是,很高兴知道,即使这只是劝阻他人的额外理由;)。

编辑2
BoltClock指出,如果有2条!important声明,则规范说它将选择最具体的一条。


7
出于好奇,您如何评估CSS样式表的性能?更好的CSS渲染速度更快?
孝义

4
@Yoshi它仍然必须寻找其他!important规则。
约翰·德沃夏克

1
@janw:我只是澄清说它确实选择了最具体的一个...我已经删除了误导性评论。
BoltClock

15
随笔:标题是有趣,如果它写着:“重要的是重要的!?”
Nik Bougalis

59
我总是读为“不重要”重要!
oɔɯǝɹ

Answers:


269

它实际上不会对性能产生任何影响。看到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

但是,可维护性的确受到了打击(如其他答案所述),这可能是您唯一反对它们的理由。


87
我喜欢你是唯一一个讨厌检查而不是假设的人。辛苦了,先生!
Moox 2012年

顺便说一下,这个对象模型不是DOM,而是CSSOM。以防万一有人想知道。
BoltClock

5
这应该是答案。我感到羞愧的是,我的回答是您的两倍。哦,亲爱的,亲爱的。有人应归功于这个人!
Michael Giovanni Pumo

3
这篇文章全部是关于解析的,我希望对性能的影响为零。解析器速度很快。问题是,在浏览器中搜索与特定元素匹配的CSS声明时,渲染期间该怎么办?没有!important专门优化规则的常见情况吗?我不这么认为,但是很难确定。Firefox中的layout / style目录为80,000行代码。
杰森·奥伦多夫

1
您检查确切来源并分享高水平知识的努力简直是非凡而令人惊奇。像您这样的人使StackOverflow如此受欢迎和值得信赖。非常感谢您的回答和分享。
Anmol Saraf 2012年

113

我认为!important就浏览器匹配规则的速度而言,这并不是天生的糟糕(它不构成选择器的一部分,而只是声明的一部分)

但是,如前所述,它将降低代码的可维护性,并可能由于将来的更改而不必要地增加代码的大小。的使用!important也可能会降低开发人员的性能。

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

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


56
“ 11个额外的字节”为可选的空格提供或占用几个字节哦,天哪
BoltClock

11
我知道...我只是在通过将挑剔提升到一个新的水平来取笑人们对表现的挑剔。
BoltClock

11
如果您真的很挑剔,那么以正确的方式进行操作所需的额外特异性通常会远远超过11个字节。
BlakeGru 2012年


10
@DisgruntledGoat:一个头脑冷静的人会意识到浪费的不是字节,而是秒,分钟,小时,天和神经元。(为什么我还在这里?)
BoltClock

59

!important有它的位置。相信我。它为我节省了很多时间,并且在找到更长,更优雅的解决问题的方法之前,作为短期解决方案通常更有用。

但是,就像大多数事情一样,它被滥用了,但是无需担心“性能”。我敢打赌,一个小的1x1 GIF在网页上的性能影响要比!important大得多。

如果您想优化页面,那么还有更多的重要路线要走;);)


8
这只是一个有趣的结局,让我们所有人微笑,只是……放松!
Michael Giovanni Pumo 2012年

12
什么驴?我要知道!
奥斯卡·布罗曼

1
@奥斯卡·布罗曼(Oscar Broman)我认为他的意思是:) :)看起来像人体解剖学的特定部分,与英语中的另一头驴具有相同的名称。“驴或驴”,这是维基百科有关驴,赦免,驴的文章的开头。我认为扬·德沃拉克先生和两名支持者是那种被字面意思(甚至是虚构的)令人反感的字眼(或笑脸)冒犯的人。但是,当您指的是驴子时,说驴是很愚蠢和不礼貌的,因为很少有非英语使用者会理解。
Dimitar Slavchev

7
@DimitarSlavchev Jan不在谈论笑脸。请参阅Michael帖子初始版本(修订版2)。
andytuba

5
@andytuba tbh,它使Dimitars的论点无效,但对他的观点无效:) :)
绝望的鬼脸

31

幕后操作是在处理CSS时,浏览器读取它,遇到一个!important属性,然后浏览器返回以应用定义的样式!important。这个额外的过程似乎只是一个很小的附加步骤,但是如果您要处理许多请求,那么性能将会受到影响。(资源)

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

开发人员在使用时的想法!important

  1. 我的摇摆式CSS无法正常工作... grrrr。
  2. 我现在应该怎么办??
  3. 然后,!important是的。...现在工作正常。

但是!important,由于我们对CSS的管理不善,所以使用它不是一种很好的方法。它产生了很多设计问题-比性能问题更糟-但它也迫使我们使用很多额外的代码行,因为我们使用覆盖其他属性,!important而CSS变得无用。相反,我们应该做的是首先很好地管理CSS,并且不要让属性相互覆盖。

我们可以使用!important。但是,只有在没有其他出路时,才应谨慎使用。

在此处输入图片说明


哪种方法更好?css的特殊性以确保元素的应用是正确的样式(这可能意味着巨大的css声明;例如,#news .article .article-title h3 a {})还是仅添加了重要标记?
丹尼斯·马丁内斯

1
@DennisMartinez它会更好,使一类的标题链接,只需添加这个..
NullPoiиteя

不,只是懒惰。坚持下去。击中。
Erik Reppen

1
我不认为casperOne会因为加载缓慢而删除了图像...
BoltClock

13

我同意您不使用它,因为这是不正确的做法,无论其性能如何。仅凭这些理由,我就尽量避免使用!important

但是关于性能的问题:不,它不应该引起注意。它可能有一定的效果,但它应该是如此的渺小,你应该不会注意到它,也不应该你担心。

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

让我以反驳性的问题回答您的问题。您可能没有考虑过的角度:您是指哪种浏览器?

每个浏览器显然都有其自己的呈现引擎,并具有自己的优化。因此,问题就变成了:每种浏览器对性能的影响是什么?也许!important在一种浏览器中表现不佳,但在另一种浏览器中却表现出色?也许在下一个版本中,情况会相反吗?

我想在这里提出的观点是,作为Web开发人员,我们不应考虑(或需要考虑)所用语言的各个语法构造对性能的影响。我们应该使用这些语法构造,因为它们是实现我们不想要的东西的正确方法,而不是因为它们的执行方式。

应该结合使用探查器来询问性能问题,以分析系统中的关键点。首先解决真正让您放慢脚步的事情。几乎可以肯定,在进入单个CSS构造之前,需要解决的问题要大得多。


很好的推理。我知道这不值得优化,但我很好奇。
janw 2012年

7

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


2
@Jan Dvorak你怎么了?
2012年

@BoltClock我指的是第一句话。
John Dvorak

4
@Enve我的问题是我希望看到一个基准,而不是作为事实提出的先验假设。我不知道这是哪一个。
John Dvorak

我认为,它会使您的代码难以维护这一事实应成为不使用它的充分理由。即使与其他较小的性能增强(例如使用ID而不是CLASS选择器)相比,我也从未经历过任何性能下降。
Henrik

7

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

作为说明,请参阅您可能要使用的原因,对此堆栈问题的答案!important

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


6

嗯...!重要还是!!重要?

让我们逐步完成此步骤:

  1. 解析器必须为每个属性检查!important,无论是否使用它-因此此处的性能差异为0
  2. 覆盖属性时,解析器必须检查被覆盖的属性是否重要!因此此处的性能差异再次为0
  3. 如果要覆盖的属性是!! important,则必须覆盖该属性-如果不使用!important,性能命中值为-1
  4. 如果要覆盖的属性是!important,它将跳过覆盖该属性-使用!important时性能提升+1
  5. 如果新属性为!important,则无论覆盖的属性为!important还是!! important,解析都必须将其覆盖-性能差异再次为0

因此,我认为!important实际上具有更好的性能,因为它可以帮助解析器跳过许多其他情况下不会跳过的属性。

就像@ryan在下面提到的那样,重写内联CSS并避免使用javascript的唯一方法是...避免不必要的性能损失的另一种方法

嗯...结果!重要很重要

并且,

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

因此,我想使用!important可以使开发人员感到满意,并且我认为这很重要:D


1
“所以我想!重要的是实际上具有更好的性能,因为它可以帮助解析器跳过很多其他情况下不会跳过的属性。” 一旦有多个!important声明,该语句将立即无效。浏览器将必须检查所有这些。因此,实际上回到了第一步。
BoltClock

1
不管您使用多少次,解析器都必须检查@BoltClock……因此,如果您有10个属性,则无论这些属性是否重要,解析器都必须进行10次检查。因此,如果您具有10个!important属性,则解析器将执行10次检查;如果您具有10个非!important属性,则解析器仍将进行10次检查。
xtrahelp.com 2012年

仍然不确定!important是否对性能有所提升,真的。。。。。。但是,我非常喜欢所有评论和讨论。我的知识正在向前迈出下一步。StackOverflow真是太神奇了:D
Anmol Saraf

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.classul .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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.