簡體   English   中英

!important 對性能有害嗎?

[英]Is !important bad for performance?

我討厭它們,它違背了 CSS 的級聯特性,如果你不小心使用它們,你最終會陷入添加更多!important的循環中。

但我想知道它們對性能有害嗎?

編輯
從(快速)回復中,我可以得出結論,它不會對性能產生(顯着)影響。 但很高興知道,即使它只是作為勸阻他人的額外論據;)。

編輯 2
BoltClock 指出,如果有 2 個!important聲明,規范說它會選擇最具體的一個。

它不應該對性能產生任何明顯的影響。 /source/layout/style/nsCSSDataBlock.cpp#572看到Firefox 的 CSS 解析器,我認為這是相關的例程,處理 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的好理由。

但是,可維護性確實受到了打擊(如其他答案所述),這可能是您反對它們的唯一論據。

我不認為!important在瀏覽器匹配規則的速度方面本質上是不好的(它不構成選擇器的一部分,只是聲明的一部分)

但是,正如已經說過的那樣,它會降低代碼的可維護性,因此可能會由於未來的更改而導致其大小不必要地增長。 !important的使用也可能會降低開發人員的性能。

如果你真的很挑剔,你也可以說!important為你的 CSS 文件增加了 11 個額外的字節,這並不是很多,但我想如果你的樣式表中有相當多的!important s,它可以加起來。

只是我的想法,不幸的是我找不到任何關於!important如何影響性能的基准。

!important有它的位置。 相信我。 在找到解決問題的更長更優雅的方法之前,它已經多次救了我,而且作為短期解決方案通常更有用。

然而,像大多數事情一樣,它被濫用了,但沒有必要擔心“性能”。 我敢打賭,與 !important 相比,一個小的 1x1 GIF 對網頁的性能影響更大。

如果你想優化你的頁面,還有更多重要的路線要走 ;) ;)

幕后發生的事情是,在處理您的 CSS 時,瀏覽器讀取它,遇到一個!important屬性,然后瀏覽器返回應用!important定義的樣式。 這個額外的過程可能看起來像是一個小的額外步驟,但是如果您要處理很多請求,那么您的性能就會受到影響。 (來源)

在你的 CSS 中使用 !important 通常意味着開發人員自戀、自私或懶惰。 尊重開發者的到來......

使用!important時開發人員的想法:

  1. 我的搖擺 CSS 不起作用... grrrr。
  2. 我現在該怎么辦??
  3. 然后!important是......現在它工作正常。

然而,使用!important並不是一個好方法,因為我們沒有很好地管理 CSS。 它產生了許多設計問題——比性能問題更糟糕——但它也迫使我們使用許多額外的代碼行,因為我們用!important覆蓋了其他屬性,並且我們的 CSS 被無用的代碼弄得亂七八糟。 相反,我們應該做的是首先很好地管理CSS,而不是讓屬性相互覆蓋。

我們可以使用!important 但是請謹慎使用它,並且只有在沒有其他出路時才使用它。

在此處輸入圖片說明

我同意你不使用它,因為無論性能如何,它都是不好的做法。 僅基於這些理由,我會盡可能避免使用!important

但在性能問題上:不,它不應該引人注目。 它可能會產生一些影響,但它應該很小,您應該永遠不會注意到它,也不應該擔心它。

如果它足夠顯眼,那么您的代碼中可能會遇到比!important更大的問題。 簡單使用您正在使用的核心語言的正常語法元素永遠不會成為性能問題。

讓我用一個反駁的問題來回答你的問題; 一個你可能沒有考慮過的角度:你指的是哪個瀏覽器?

每個瀏覽器顯然都有自己的渲染引擎,並進行了自己的優化。 所以現在的問題變成了:每個瀏覽器的性能影響是什么? 也許!important在一種瀏覽器中表現不佳,但在另一種瀏覽器中表現良好? 也許在下一個版本中,情況會相反?

我想我的觀點是,我們作為 Web 開發人員不應該考慮(或需要考慮)我們正在使用的語言的單個語法結構的性能影響。 我們應該使用這些語法結構,因為它們是實現我們想要做的事情的正確方法,而不是因為它們的執行方式。

性能問題應該結合使用分析器來分析系統中的夾點。 首先解決真正讓你慢下來的事情。 在您深入到單個 CSS 構造的級別之前,幾乎可以肯定還有更大的問題需要您解決。

它不會顯着影響性能。 但是,它確實會降低代碼的可維護性,因此從長遠來看可能會降低性能。

之前不得不多次使用!important ,我個人注意到在使用它時沒有明顯的性能下降。

請注意出於您可能想要使用!important的原因,請參閱此堆棧問題的答案

另外,我要提一些其他人都沒有提到的東西。 !important是在編寫 javascript 函數的情況下覆蓋內聯 css 的唯一方法(即使只有一點點也會影響您的性能)。 因此,如果您需要覆蓋內聯 css,它實際上可以為您節省一些性能時間。

嗯...!重要還是!!重要?

讓我們一步一步來:

  1. 解析器必須檢查每個屬性的 !important,無論您是否使用它 - 所以這里的性能差異是 0
  2. 覆蓋屬性時,解析器必須檢查被覆蓋的屬性是否重要 - 所以這里的性能差異再次為 0
  3. 如果被覆蓋的屬性是 !!important,它必須覆蓋該屬性 - 不使用 !important 的性能命中 -1
  4. 如果被覆蓋的屬性是 !important,它會跳過覆蓋該屬性 - 使用 !important 的性能提升 +1
  5. 如果新屬性是 !important,則無論被覆蓋的屬性是 !important 還是 !!important,解析都必須覆蓋它 - 性能差異再次為 0

所以我猜 !important 實際上具有更好的性能,因為它可以幫助解析器跳過許多其他情況下不會跳過的屬性。

正如@ryan 在下面提到的,覆蓋內聯 css 並避免使用 javascript 的唯一方法......所以另一種避免不必要的性能影響的方法

嗯...結果證明 !important 很重要

並且,

  • 使用 !important 為開發人員節省了大量時間
  • 有時可以使您免於重新設計整個 css
  • 有時 html 或父 css 文件不在您的控制范圍內,因此它可以挽救您的生命
  • 顯然可以防止 !important 元素被其他 !!important 元素意外覆蓋
  • 有時瀏覽器不會選擇正確的屬性,而不會在選擇器中過於具體,因此使用 !important 真的變得很重要,並且可以避免在 css 中編寫大量特定的 css 選擇器。 所以我想即使你使用更多的字節來寫!重要的,它也可以在其他地方節省你的字節。 我們都知道,css 選擇器可能會變得混亂。

所以我想使用 !important 可以讓開發人員高興,我認為這非常重要:D

我無法預見!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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM