Czy! Ważne jest złe dla wydajności?

193

Nienawidzę ich, to przeciwstawia się kaskadowej naturze CSS, a jeśli nie użyjesz ich ostrożnie, skończysz w pętli dodawania kolejnych !important.

Ale chcę wiedzieć, czy mają zły wpływ na wydajność?

EDYCJA
Na podstawie (szybkich) odpowiedzi mogę stwierdzić, że nie będzie to miało (znaczącego) wpływu na wydajność. Ale miło jest wiedzieć, nawet jeśli jest to dodatkowy argument zniechęcający innych;).

EDIT 2
BoltClock wskazał, że jeśli są 2 !importantdeklaracje, specyfikacja mówi, że wybierze najbardziej konkretną.

janw
źródło
7
z ciekawości, jak oceniasz wydajność arkusza stylów CSS? lepiej renderować CSS szybciej czy coś?
xiaoyi,
4
@Yoshi wciąż musi szukać innych !importantzasad.
John Dvorak,
1
@janw: Właśnie wyjaśniłem, że wybiera najbardziej konkretny ... Usunąłem wprowadzający w błąd komentarz.
BoltClock
15
losowa myśl: tytuł byłby o wiele zabawniejszy, gdyby brzmiał: „Czy! ważne jest ważne?”
Nik Bougalis,
59
zawsze czytam! ważne jako „
nieważne

Odpowiedzi:

269

To nie powinno mieć żadnego wpływu na wydajność. Widząc Firefoksa CSS parser na/source/layout/style/nsCSSDataBlock.cpp#572 i myślę, że jest istotne rutyna, obsługa nadpisywania reguł CSS.

wydaje się to po prostu sprawdzeniem „ważnego”.

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

Również komentarze na 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 używa parsera z góry na dół napisanego ręcznie. W obu przypadkach każdy plik CSS jest analizowany w obiekcie StyleSheet, każdy obiekt zawiera reguły CSS.

  2. Firefox tworzy następnie drzewa stylów kontekstowych, które zawierają wartości końcowe (po zastosowaniu wszystkich reguł we właściwej kolejności)

CSS Parser Firefox

Od: http://taligarsiel.com/Projects/howbrowserswork1.htm#CSS_parsing

Teraz możesz łatwo zobaczyć, na przykład w przypadku opisanego powyżej modelu obiektowego, analizator składni może łatwo oznaczyć reguły, na które ma wpływ !important, bez większych kosztów. Spadek wydajności nie jest dobrym argumentem przeciwko !important.

Jednak łatwość konserwacji wymaga trafienia (jak wspomniano w innych odpowiedziach), co może być twoim jedynym argumentem przeciwko nim.

Anirudh Ramanathan
źródło
87
Podoba mi się, że tylko ty niepokoiłeś się sprawdzaniem zamiast zakładania. Świetna robota, proszę pana!
Moox
Nawiasem mówiąc, ten model obiektowy nie jest DOM ... to CSSOM. Na wypadek, gdyby ktoś się zastanawiał.
BoltClock
5
To powinna być odpowiedź. Wstydzę się, że moja odpowiedź ma dwa razy więcej punktów niż twoja. Och kochanie och kochanie. Niech ktoś da temu mężczyźnie kredyt tam, gdzie jest to konieczne!
Michael Giovanni Pumo,
3
Ten post dotyczy parsowania i spodziewam się, że wpływ na wydajność wyniesie zero. Parsery są szybkie. Pytanie brzmi: co z renderowaniem, gdy przeglądarka szuka deklaracji CSS pasujących do określonego elementu? Czy często zdarza się, że nie ma !importantspecjalnie zoptymalizowanych reguł? Nie sądzę, ale trudno być pewnym; katalog layout / style w Firefoksie zawiera 80 000 linii kodu.
Jason Orendorff,
1
Twoje wysiłki, aby sprawdzić dokładne źródło i podzielić się tym wysokim poziomem wiedzy, są po prostu niezwykłe i niesamowite. Ludzie tacy jak ty sprawiają, że StackOverflow jest tak popularny i godny zaufania. Dziękuję bardzo za udzielenie odpowiedzi i udostępnienie tego.
Anmol Saraf,
113

Nie sądzę, aby było !importantto z natury złe z punktu widzenia szybkości, z jaką przeglądarka dopasowuje reguły (nie stanowi części selektora, tylko część deklaracji)

Jednak, jak już wspomniano, zmniejszy to łatwość konserwacji twojego kodu, a zatem prawdopodobnie spowoduje, że jego rozmiar będzie niepotrzebnie powiększał się z powodu przyszłych zmian. Zastosowanie !importantprawdopodobnie obniżyłoby również wydajność programistów.

Jeśli jesteś naprawdę wybredny, możesz także powiedzieć, że !importantdodaje 11 dodatkowych bajtów do pliku CSS, to nie jest tak naprawdę dużo, ale myślę, że jeśli masz sporo !importants w swoim arkuszu stylów, może to dodać.

Tylko moje przemyślenia, niestety nie mogłem znaleźć żadnych testów porównawczych, które !importantmogłyby wpłynąć na wydajność.

Sean
źródło
56
„11 dodatkowych bajtów” daje lub bierze kilka bajtów na opcjonalne białe znaki, o Boże, białe znaki
BoltClock
11
Wiem ... wyśmiewam się z tego, jak bardzo wybredni stają się ludzie, jeśli chodzi o wydajność, przenosząc tę ​​wybredność na wyższy poziom.
BoltClock
11
jeśli jesteś naprawdę wybredny, dodatkowa specyficzność potrzebna do zrobienia tego we właściwy sposób często przekracza 11 bajtów.
BlakeGru,
10
@DisgruntledGoat: Osoba o zrównoważonym poziomie uświadomiłaby sobie, że nie marnuje się bajtów, ale sekundy, minuty, godziny, dni i neurony. (Dlaczego wciąż tu jestem?)
BoltClock
59

!importantma swoje miejsce. Zaufaj mi co do tego. Oszczędzało mi to wiele razy i często jest bardziej przydatne jako rozwiązanie krótkoterminowe, zanim można będzie znaleźć dłuższą i bardziej elegancką metodę rozwiązania problemu.

Jednak, jak większość rzeczy, był nadużywany, ale nie trzeba się martwić o „wydajność”. Założę się, że jeden mały 1x1 GIF ma więcej wyników na stronie internetowej niż to!

Jeśli chcesz zoptymalizować swoje strony, jest wiele innych ! Ważnych dróg do pokonania;);)

Michael Giovanni Pumo
źródło
8
To było trochę zabawne zakończenie, wszyscy się uśmiechnijmy i po prostu ... zrelaksuj się!
Michael Giovanni Pumo,
12
Jaki osioł Muszę wiedzieć!
Oscar Broman,
1
@Oscar Broman Myślę, że ma na myśli to :) :) wygląda jak szczególna część ludzkiej anatomii, która ma wspólną nazwę z inną nazwą osła w języku angielskim. „Osioł lub osioł” - to początek artykułu w Wikipedii na temat osła, ułaskawienia, osła. Zakładam, że pan Jan Dvorak i dwóch upvoterów należą do osób obrażonych dosłownie każdym słowem (lub buźką), które są nawet zdalnie (lub w tym przypadku wyobrażone) obraźliwe. Jednak powiedzenie osła, gdy masz na myśli tyłek, jest dość głupie i nieuprzejme, ponieważ niewielu nie mówiących po angielsku to zrozumie.
Dimitar Slavchev,
7
@DimitarSlavchev Jan nie mówił o buźce. Zobacz wstępną wersję posta Michaela (wersja 2).
andytuba,
5
@andytuba tbh, unieważnia argument Dimitarsa, ale nie jego punkt :) :)
Grimace of Despair
31

Za kulisami dzieje się to, że gdy twój CSS jest przetwarzany, przeglądarka go odczytuje, napotyka !importantatrybut, a przeglądarka wraca, aby zastosować style określone przez !important. Ten dodatkowy proces może wydawać się małym dodatkowym krokiem, ale jeśli obsłużysz wiele żądań, to poprawisz wydajność. (Źródło)

Używanie! Ważne w twoim CSS zwykle oznacza programistę narcystyczne i samolubne lub leniwe. Szanuj twórców ...

Myślenie programisty przy użyciu !important:

  1. Mój bujający się CSS nie działa ... grrrr.
  2. Co mam teraz zrobić??
  3. A potem !importanttak ... teraz działa dobrze.

Jednak nie jest to dobre podejście do korzystania !importanttylko dlatego, że nie zarządzaliśmy dobrze CSS. Powoduje to wiele problemów projektowych - gorszych niż problemy z wydajnością - ale zmusza nas również do korzystania z wielu dodatkowych wierszy kodu, ponieważ zastępujemy inne właściwości, !importanta nasz CSS jest zaśmiecony niepotrzebnym kodem. Zamiast tego powinniśmy najpierw bardzo dobrze zarządzać CSS i nie dopuścić, aby właściwości się przesłoniły.

My może używać !important. Ale używaj go oszczędnie i tylko wtedy, gdy nie ma innego wyjścia.

wprowadź opis zdjęcia tutaj

NullPoiиteя
źródło
Która metoda jest lepsza? Specyfika w css zapewniająca zastosowanie elementu to właściwe style (co może oznaczać ogromną instrukcję css; np. #News .article .article-title h3 a {}) lub po prostu dodanie ważnego znacznika?
Dennis Martinez,
1
@DennisMartinez lepiej byłoby stworzyć klasę dla linku do tytułu i po prostu dodać to ...
NullPoiиteя
Nie, po prostu leniwy. Złapać kij. Trafienie.
Erik Reppen,
1
Nie sądzę, aby casperOne usunął zdjęcia tylko dlatego, że ładowały się wolno ...
BoltClock
13

Zgadzam się z tobą, że go nie używasz, ponieważ jest to zła praktyka, niezależnie od wydajności. Z tych samych powodów unikałbym używania!important to możliwe.

Ale w kwestii wydajności: nie, nie powinno być zauważalne. Może to mieć jakiś wpływ, ale powinno być tak małe, że nigdy nie powinieneś tego zauważyć, ani nie powinieneś martwić się o niego.

Jeśli jest to wystarczająco znaczące, aby być zauważalnym, prawdopodobnie masz większe problemy w kodzie niż tylko !important. Proste użycie normalnego elementu składni podstawowych języków, których używasz, nigdy nie będzie stanowić problemu z wydajnością.

Pozwól, że odpowiem na twoje pytanie w odpowiedzi na pytanie retoryczne; kąt, którego prawdopodobnie nie wziąłeś pod uwagę: o jaką przeglądarkę masz na myśli?

Każda przeglądarka ma oczywiście własny silnik renderowania z własnymi optymalizacjami. Pojawia się więc pytanie: jakie są konsekwencje wydajności w każdej przeglądarce? Być może !importantdziała źle w jednej przeglądarce, ale naprawdę dobrze w innej? A może w następnych wersjach będzie odwrotnie?

Chyba tutaj mam na myśli to, że my, programiści stron internetowych, nie powinniśmy myśleć (lub trzeba myśleć o) skutkach poszczególnych konstrukcji składni używanych przez nas języków. Powinniśmy używać tych konstrukcji składniowych, ponieważ są one właściwym sposobem na osiągnięcie tego, czego nie chcemy, ze względu na ich wydajność.

Pytania dotyczące wydajności należy zadawać w połączeniu z wykorzystaniem profilerów do analizy, gdzie znajdują się punkty ściskania w twoim systemie. Najpierw napraw rzeczy, które naprawdę Cię spowalniają. Prawie na pewno będą o wiele większe problemy do rozwiązania, zanim przejdziesz do poziomu poszczególnych konstrukcji CSS.

SDC
źródło
Niezłe rozumowanie. Wiem, że nie warto tego optymalizować, ale jestem po prostu ciekawy.
janw
7

Nie wpływa to zauważalnie na wydajność. Zmniejsza to jednak łatwość utrzymania kodu i dlatego może obniżyć wydajność na dłuższą metę.

Henrik
źródło
2
@Jan Dvorak, jaki masz problem?
Enve,
@BoltClock Mam na myśli pierwsze zdanie.
John Dvorak,
4
@ Enve moim problemem jest to, że chciałbym zobaczyć punkt odniesienia, a nie założenia apriori przedstawione jako fakty. Nie wiem który to jest ten.
John Dvorak,
Argumentowałbym, że fakt, że utrudnia to utrzymanie kodu, powinien być wystarczającym argumentem, aby go nie używać. Nigdy nie doświadczyłem żadnego spadku wydajności, nawet w porównaniu z innymi drobnymi ulepszeniami wydajności, takimi jak używanie ID zamiast selektorów klasy.
Henrik,
7

Musiałem użyć !important kilka razy wcześniej, ale osobiście nie zauważyłem żadnego widocznego spadku wydajności podczas jego używania.

Jako notatkę patrz z odpowiedzią na to pytanie stosu z powodu, którego możesz chcieć użyć!important .

Wspomnę też o czymś, o czym nie wspomnieli inni. !importantjest jedynym sposobem na zastąpienie wbudowanego css bez pisania funkcji javascript (co wpłynie na twoją wydajność, nawet jeśli tylko trochę). Więc może faktycznie zaoszczędzić trochę czasu na wydajność, jeśli musisz zastąpić wbudowany css.

Ryan
źródło
6

hmm ...! ważne czy !! ważne?

Przejdźmy przez ten krok po kroku:

  1. Analizator składni musi sprawdzić! Ważne dla każdej właściwości, niezależnie od tego, czy jej używasz, czy nie - więc różnica wydajności wynosi tutaj 0
  2. Podczas nadpisywania właściwości analizator składni musi sprawdzić, czy nadpisywana właściwość jest! Ważna, czy nie - więc różnica w wydajności tutaj wynosi ponownie 0
  3. Jeśli zastępowana właściwość jest !! ważna, musi nadpisać właściwość - hit wydajności -1 za nieużywanie! Ważne
  4. Jeśli zastępowana właściwość jest! Ważna, pomija nadpisywanie właściwości - wzrost wydajności o +1 za użycie! Ważne
  5. Jeśli nowa właściwość jest! Ważna, analiza musi ją zastąpić, niezależnie od tego, że właściwość, która ma zostać zastąpiona jest!

Sądzę więc, że ważne ma lepszą wydajność, ponieważ może pomóc parserowi pominąć wiele właściwości, których inaczej nie pominąłby.

i jak wspomniano poniżej @ryan, jedynym sposobem na zastąpienie wbudowanego css i uniknięcie używania javascript ... więc inny sposób na uniknięcie niepotrzebnego spadku wydajności

hmm ... okazuje się, że! ważne jest ważne

i również,

  • Korzystanie z! Ważna oszczędność czasu dla programisty
  • czasami ratuje Cię przed przeprojektowaniem całego css
  • czasami html lub nadrzędny plik css nie jest pod twoją kontrolą, więc ratuje ci tam życie
  • oczywiście zapobiega przypadkowemu zastąpieniu ważnych elementów przez inne ważne elementy
  • a czasami przeglądarki po prostu nie wybierają właściwych właściwości, nie będąc zbyt szczegółowymi w selektorach, więc użycie! ważne naprawdę staje się ważne i oszczędza Ci pisania wielu ton selektorów css w twoim css. więc myślę, że nawet jeśli użyjesz więcej bajtów do pisania! ważne, to może zaoszczędzić bajty w innych miejscach. i wszyscy wiemy, selektory css mogą się bałaganić.

Wydaje mi się, że użycie! Ważne może uszczęśliwić programistów i myślę, że to bardzo ważne : D

xtrahelp.com
źródło
1
„Myślę, że! Ważne ma lepszą wydajność, ponieważ może pomóc analizatorowi pominąć wiele właściwości, których inaczej nie pominąłby”. To oświadczenie jest natychmiast anulowane, gdy masz wiele !importantdeklaracji. Przeglądarka będzie musiała sprawdzić je wszystkie. Tak naprawdę to wraca do kroku 1.
BoltClock
1
@BoltClock analizator składni musi sprawdzić właściwość bez względu na to, ile razy go użyjesz ... więc jeśli masz 10 właściwości, analizator składni musi to sprawdzić 10 razy, niezależnie od tego, czy te właściwości są! Ważne czy nie. więc jeśli masz 10! ważnych właściwości, parser wykonuje czek 10 razy, a jeśli masz 10 nie! ważnych właściwości, parser nadal sprawdza 10 razy ... ma sens?
xtrahelp.com,
Nadal nie jestem pewien, czy! Ważne jest zwiększenie wydajności, czy nie, naprawdę ... ale bardzo lubię wszystkie komentarze i dyskusje. Moja wiedza robi kolejny krok naprzód. StackOverflow jest po prostu niesamowity: D
Anmol Saraf,
4

Nie mogę przewidzieć !importantutrudniania wydajności, zresztą i tak z natury. Jeśli jednak Twój CSS jest pełen zagadek !important, oznacza to, że przekroczyłeś kwalifikujące się selektory i jesteś zbyt specyficzny oraz że zabrakło Ci rodziców lub kwalifikatorów, aby dodać specyfikę. W związku z tym Twój CSS będą stały nadęty (która będzie utrudniać wydajność) i trudne do utrzymania.

Ważny mem reguły CSS

Jeśli chcesz napisać efektywne CSS następnie chcesz być tylko tak dokładnie, jak trzeba być i pisać modułową CSS . Wskazane jest, aby powstrzymać się od używania identyfikatorów (z skrótami), łączenia selektorów lub kwalifikujących selektorów.

Identyfikatory poprzedzone #w CSS są złośliwie specyficzne, do tego stopnia, że 255 klas nie zastąpi identyfikatora (skrzypce: @Faust ). Identyfikatory mają również głębszy problem z routingiem, muszą być unikalne, co oznacza, że ​​nie można ich ponownie użyć do powielonych stylów, więc w końcu piszesz liniowy css z powtarzającymi się stylami. Konsekwencje tego będą różne dla poszczególnych projektów, w zależności od skali, ale możliwość konserwacji będzie ogromnie ucierpiała, aw skrajnych przypadkach również wydajność.

Jak możesz dodać specyficzność bez !important, łączenia, kwalifikacji lub dokumentów tożsamości (a mianowicie #)

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

Okej, więc jak to działa?

Pierwszy i drugi przykład działają tak samo, pierwszy to dosłownie klasa, a drugi to selektor atrybutów. Klasy i selektory atrybutów mają identyczną specyficzność. .eg1/2-barnie dziedziczy koloru.eg1/2-foo ponieważ ma swoją własną zasadę.

Trzeci przykład wygląda jak kwalifikujące się lub łączące selektory, ale tak nie jest. Tworzenie łańcuchów ma miejsce, gdy prefiksujesz selektory rodzicom, przodkom i tak dalej; to dodaje specyficzności. Kwalifikacja jest podobna, ale definiujesz element, do którego ma zastosowanie selektor. kwalifikacje: ul.classi łączenie:ul .class

Nie jestem pewien, jak nazwałbyś tę technikę, ale zachowanie jest celowe i udokumentowane przez W3C

Powtarzane wystąpienia tego samego prostego selektora są dozwolone i zwiększają swoistość.

Co dzieje się, gdy specyfika między dwiema regułami jest identyczna?

Jak wskazał @BoltClock , jeśli istnieje wiele! Ważnych deklaracji, wówczas specyfikacja określa, że najbardziej konkretna powinna mieć pierwszeństwo.

W poniższym przykładzie, zarówno .fooi .barmają identyczną specyficzność, więc fallsback zachowanie do kaskadowego rodzaju CSS, przy czym ostatnia reguła deklarowanej zastrzeżeń CSS pierwszeństwa tj .foo.

HTML

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

CSS

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

JSFiddle

Jack Tuck
źródło