Apakah penting buruk untuk kinerja?

192

Saya benci mereka, itu menentang sifat cascading dari CSS, dan jika Anda tidak menggunakannya dengan hati-hati, Anda berakhir dengan menambahkan lebih banyak !important.

Tapi saya ingin tahu apakah mereka buruk untuk kinerja?

EDIT
Dari balasan (cepat) yang saya dapat simpulkan itu tidak akan berdampak signifikan pada kinerja. Tapi itu menyenangkan untuk diketahui, bahkan jika itu hanya sebagai argumen tambahan untuk mengecilkan hati orang lain;).

EDIT 2
BoltClock menunjukkan bahwa jika ada 2 !importantdeklarasi spesifikasi mengatakan akan memilih yang paling spesifik.

janw
sumber
7
karena penasaran, bagaimana Anda mengevaluasi kinerja stylesheet CSS? lebih baik membuat CSS lebih cepat atau sesuatu?
xiaoyi
4
@Yoshi masih harus mencari !importantaturan lain .
John Dvorak
1
@janw: Saya baru saja mengklarifikasi bahwa ia memilih yang paling spesifik ... Saya telah menghapus komentar yang menyesatkan.
BoltClock
15
pemikiran acak: Judul akan jauh lebih lucu jika berbunyi: "Apakah penting penting?"
Nik Bougalis
59
saya selalu membaca! penting sebagai 'tidak penting'
oɔɯǝɹ

Jawaban:

269

Seharusnya tidak memiliki efek pada kinerja. Melihat parser CSS firefox di/source/layout/style/nsCSSDataBlock.cpp#572 dan saya pikir itu adalah rutin yang relevan, menangani menimpa aturan CSS.

sepertinya hanya pemeriksaan sederhana untuk "penting".

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

Juga, komentar di 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 menggunakan pengurai top down yang ditulis secara manual. Dalam kedua kasus, setiap file CSS diuraikan menjadi objek StyleSheet, setiap objek berisi aturan CSS.

  2. Firefox kemudian membuat pohon konteks gaya yang berisi nilai akhir (setelah menerapkan semua aturan dalam urutan yang benar)

CSS Parser Firefox

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

Sekarang, Anda dapat dengan mudah melihat, seperti halnya dengan Object Model yang dijelaskan di atas, parser dapat menandai aturan yang dipengaruhi oleh !importantmudah, tanpa banyak biaya berikutnya. Degradasi kinerja bukanlah argumen yang bagus !important.

Namun, rawatan memang mendapat pukulan (seperti jawaban lain yang disebutkan), yang mungkin menjadi satu-satunya argumen Anda terhadap mereka.

Anirudh Ramanathan
sumber
87
Saya suka bahwa Anda satu-satunya yang repot memeriksa daripada berasumsi. Pak kerja bagus!
Moox
Model objek ini bukan DOM, omong-omong ... itu adalah CSSOM. Kalau-kalau ada yang bertanya-tanya.
BoltClock
5
Ini seharusnya jawabannya. Saya merasa malu bahwa tanggapan saya dua kali lipat dari poin Anda. Oh sayang oh sayang. Seseorang memberikan kredit kepada pria ini di tempat yang seharusnya!
Michael Giovanni Pumo
3
Posting ini adalah semua tentang penguraian, dan saya berharap dampak kinerja di sana menjadi nol. Parser cepat. Pertanyaannya adalah, bagaimana dengan saat rendering, ketika browser mencari deklarasi CSS yang cocok dengan elemen tertentu? Apakah kasus umum di mana tidak ada !importantaturan yang dioptimalkan secara khusus? Saya kira tidak, tetapi sulit untuk memastikannya; direktori tata letak / gaya di Firefox adalah 80.000 baris kode.
Jason Orendorff
1
Upaya Anda untuk memeriksa sumber yang tepat dan membagikan pengetahuan tingkat tinggi ini sungguh luar biasa dan menakjubkan. Orang-orang seperti Anda adalah orang-orang yang membuat StackOverflow begitu populer dan dapat dipercaya. Terima kasih banyak untuk menjawab dan membagikan ini.
Anmol Saraf
113

Saya tidak berpikir itu !importantsecara inheren buruk dalam hal seberapa cepat browser cocok dengan aturan (tidak membentuk bagian dari pemilih, hanya bagian dari deklarasi)

Namun, seperti yang telah dinyatakan, ini akan mengurangi kelestarian kode Anda, dan dengan demikian kemungkinan menyebabkannya tumbuh dalam ukuran yang tidak perlu karena perubahan di masa depan. Penggunaan !importantjuga kemungkinan akan mengurangi kinerja pengembang.

Jika Anda benar - benar pilih - pilih, Anda juga bisa mengatakan bahwa !importantmenambahkan 11 byte tambahan ke file CSS Anda, ini tidak terlalu banyak, tapi saya kira jika Anda memiliki beberapa !importants dalam stylesheet Anda itu bisa bertambah.

Hanya pikiran saya, sayangnya saya tidak dapat menemukan tolok ukur tentang bagaimana !importantdapat mempengaruhi kinerja.

Sean
sumber
56
"11 byte tambahan" memberi atau mengambil beberapa byte untuk spasi kosong opsional oh tuhan ruang kosong
BoltClock
11
Saya tahu ... Saya hanya mengolok-olok bagaimana orang yang sangat pilih-pilih dapatkan ketika datang ke kinerja, dengan membawa rasa pilih-pilih ke tingkat berikutnya.
BoltClock
11
jika Anda benar- benar pilih - pilih, kekhususan tambahan yang diperlukan untuk melakukannya dengan cara yang benar seringkali jauh melebihi 11 byte.
BlakeGru
10
@DisgruntledGoat: Seseorang yang berkepala dingin akan menyadari bahwa itu bukan byte yang disia-siakan tetapi detik, menit, jam, hari, dan neuron. (Mengapa saya masih di sini?)
BoltClock
59

!importantmemiliki tempatnya. Percayalah pada yang itu. Ini menyelamatkan saya berkali-kali dan seringkali lebih berguna sebagai solusi jangka pendek, sebelum metode yang lebih panjang dan lebih elegan untuk masalah Anda dapat ditemukan.

Namun, seperti kebanyakan hal, itu telah disalahgunakan, tetapi tidak perlu khawatir tentang 'kinerja'. Saya berani bertaruh satu GIF 1x1 kecil memiliki lebih banyak hit kinerja pada halaman web daripada!

Jika Anda ingin mengoptimalkan halaman Anda, ada banyak lagi ! Rute penting untuk diambil;);)

Michael Giovanni Pumo
sumber
8
Itu hanya akhir yang menyenangkan, mari kita semua tersenyum dan hanya ... santai!
Michael Giovanni Pumo
12
Keledai apa Aku harus tahu!
Oscar Broman
1
@Oscar Broman Saya pikir maksudnya :) :) terlihat seperti bagian tertentu dari anatomi manusia yang memiliki nama yang sama dengan nama lain untuk keledai dalam bahasa Inggris. "Keledai atau keledai," - itulah awal artikel wikipedia tentang keledai, pengampunan, keledai. Saya berasumsi bahwa Tn. Jan Dvorak dan dua orang yang memilih di antara orang-orang yang tersinggung oleh setiap kata (atau smiley) yang secara harfiah bahkan ofensif (atau dalam hal ini imajiner) ofensif. Namun, mengatakan keledai ketika Anda mengatakan keledai itu sangat bodoh dan tidak sopan karena hanya sedikit penutur bahasa Inggris yang memahaminya.
Dimitar Slavchev
7
@DimitarSlavchev Jan tidak berbicara tentang senyuman itu. Lihat versi awal tulisan Michael (revisi 2).
andytuba
5
@andytuba tbh, itu membantah argumen Dimitars, tapi bukan maksudnya :) :)
Meringis dari Despair
31

Apa yang terjadi di sini di belakang layar adalah ketika CSS Anda sedang diproses, browser membacanya, menemukan !importantatribut, dan browser kembali untuk menerapkan gaya yang ditentukan oleh !important. Proses ekstra ini mungkin tampak seperti langkah tambahan kecil, tetapi jika Anda melayani banyak permintaan, maka Anda akan mendapatkan kinerja yang baik. (Sumber)

Menggunakan! Penting dalam CSS Anda biasanya berarti pengembang narsis & egois atau malas. Hormati para devs yang akan datang ...

Pemikiran pengembang saat menggunakan !important:

  1. CSS goyang saya tidak berfungsi ... grrrr.
  2. Apa yang harus saya lakukan sekarang??
  3. Dan kemudian !importantya .... sekarang berfungsi dengan baik.

Namun itu bukan pendekatan yang baik untuk digunakan !importanthanya karena kami tidak mengelola CSS dengan baik. Ini menciptakan banyak masalah desain - yang lebih buruk daripada masalah kinerja - tetapi juga memaksa kita untuk menggunakan banyak baris kode tambahan karena kita mengesampingkan properti lain dengan !importantdan CSS kita menjadi berantakan dengan kode yang tidak berguna. Yang harus kita lakukan adalah mengelola CSS terlebih dahulu dengan sangat baik, dan tidak membiarkan properti saling menimpa.

Kita bisa menggunakan !important. Tetapi gunakanlah dengan hemat dan hanya bila tidak ada jalan keluar lain.

masukkan deskripsi gambar di sini

NullPoiиteя
sumber
Metode mana yang lebih baik? Kekhususan dalam css untuk memastikan elemen diterapkan gaya yang tepat (yang bisa berarti pernyataan css besar; misalnya #news .article .article-title h3 a {}) atau hanya menambahkan tag penting?
Dennis Martinez
1
@DennisMartinez akan lebih baik membuat kelas untuk tautan judul dan cukup tambahkan ini ..
NullPoiиteя
Tidak, hanya malas. Dapatkan tongkat. Memukul.
Erik Reppen
1
Saya tidak berpikir casperSatu menghapus gambar hanya karena mereka lambat memuat ...
BoltClock
13

Saya setuju dengan Anda untuk tidak menggunakannya karena ini adalah praktik yang buruk, apa pun kinerjanya. Dengan alasan itu saja, saya akan menghindari penggunaan !importantsedapat mungkin.

Tetapi pada pertanyaan kinerja: Tidak, itu seharusnya tidak terlihat. Ini mungkin memiliki beberapa efek, tetapi itu harus sangat kecil sehingga Anda tidak boleh menyadarinya, juga tidak perlu khawatir.

Jika cukup signifikan untuk diperhatikan maka kemungkinan Anda memiliki masalah yang lebih besar dalam kode Anda daripada sekadar !important. Penggunaan sederhana elemen sintaksis normal bahasa inti yang Anda gunakan tidak akan pernah menjadi masalah kinerja.

Biarkan saya menjawab pertanyaan Anda dengan pertanyaan retoris sebagai imbalan; sudut yang mungkin tidak Anda pertimbangkan: Peramban mana yang Anda maksud?

Setiap browser jelas memiliki mesin rendering sendiri, dengan optimisasi sendiri. Jadi pertanyaannya sekarang menjadi: apa implikasi kinerja di setiap browser? Mungkin !importantberkinerja buruk di satu browser tetapi sangat baik di browser lain? Dan mungkin dalam versi berikutnya, itu akan menjadi sebaliknya?

Saya kira maksud saya di sini adalah bahwa kita sebagai pengembang web tidak boleh memikirkan (atau perlu memikirkan) implikasi kinerja dari sintaksis individu dari bahasa yang kita gunakan. Kita harus menggunakan konstruksi sintaksis karena mereka adalah cara yang tepat untuk mencapai apa yang kita inginkan bukan karena kinerjanya.

Pertanyaan kinerja harus ditanyakan sehubungan dengan penggunaan profiler untuk menganalisis di mana titik-titik terjepit dalam sistem Anda. Perbaiki hal-hal yang benar-benar memperlambat Anda terlebih dahulu. Hampir pasti ada masalah yang jauh lebih besar bagi Anda untuk diperbaiki sebelum Anda turun ke tingkat konstruksi CSS individu.

SDC
sumber
Alasan yang bagus. Saya tahu ini tidak layak untuk dioptimalkan tetapi saya hanya ingin tahu.
janw
7

Itu tidak terasa mempengaruhi kinerja. Namun hal itu mengurangi kelestarian kode Anda, dan karena itu cenderung menurunkan kinerja dalam jangka panjang.

Henrik
sumber
2
@ Jan Dvorak apa masalah Anda?
Enve
@BoltClock Saya merujuk pada kalimat pertama.
John Dvorak
4
@Enve masalah saya adalah bahwa saya ingin melihat tolok ukur, bukan asumsi apriori yang disajikan sebagai fakta. Saya tidak tahu yang mana yang ini.
John Dvorak
Saya berpendapat bahwa fakta bahwa itu membuat kode Anda lebih sulit untuk dipelihara harus menjadi argumen yang cukup untuk tidak menggunakannya. Saya tidak pernah mengalami penurunan kinerja, bahkan jika dibandingkan dengan peningkatan kinerja kecil lainnya seperti menggunakan ID dan bukan penyeleksi CLASS.
Henrik
7

Setelah harus menggunakan !importantbeberapa kali sebelumnya, saya pribadi melihat tidak ada kinerja yang terlihat saat menggunakannya.

Sebagai catatan, lihat jawaban untuk pertanyaan tumpukan ini karena alasan yang mungkin ingin Anda gunakan !important.

Juga saya akan menyebutkan sesuatu yang gagal disebutkan oleh orang lain. !importantadalah satu-satunya cara untuk menimpa inline css singkat menulis fungsi javascript (yang akan mempengaruhi kinerja Anda jika bahkan hanya sedikit). Jadi itu sebenarnya bisa menghemat waktu kinerja jika Anda perlu mengganti inline css.

Ryan
sumber
6

hmm ...! penting atau !! penting?

Mari kita lakukan langkah demi langkah:

  1. Parser harus memeriksa! Penting untuk setiap properti, terlepas dari apakah Anda menggunakannya atau tidak - jadi perbedaan kinerja di sini adalah 0
  2. Saat menimpa properti, parser harus memeriksa apakah properti yang ditimpa itu penting atau tidak - jadi perbedaan kinerja di sini adalah 0 lagi
  3. Jika properti yang ditimpa adalah penting, properti harus ditimpa - kinerja hit -1 karena tidak menggunakan! Penting
  4. Jika properti yang ditimpa adalah penting, properti akan ditimpa - peningkatan kinerja +1 untuk menggunakan! Penting
  5. Jika properti baru penting, parse harus menimpanya terlepas dari properti yang ditimpa adalah penting atau penting - perbedaan kinerja 0 lagi

Jadi saya kira! Penting sebenarnya memiliki kinerja yang lebih baik karena dapat membantu parser melewati banyak properti yang tidak akan dilewati sebaliknya.

dan seperti @ryan sebutkan di bawah ini, satu-satunya cara untuk mengganti inline css dan menghindari penggunaan javascript ... jadi cara lain untuk menghindari hit performa yang tidak perlu

hmm ... ternyata! penting itu penting

dan juga,

  • menggunakan! penting menghemat banyak waktu untuk pengembang
  • terkadang menyelamatkan Anda dari mendesain ulang seluruh css
  • terkadang html atau file css induk tidak ada dalam kendali Anda, sehingga menyelamatkan hidup Anda di sana
  • jelas mencegah! elemen penting tidak sengaja ditimpa oleh elemen penting lainnya
  • dan kadang-kadang browser hanya tidak memilih properti yang tepat, tanpa terlalu spesifik dalam pemilih, jadi menggunakan! penting benar-benar menjadi penting dan menyelamatkan Anda dari menulis ton penyeleksi css tertentu di css Anda. jadi saya kira bahkan jika Anda menggunakan lebih banyak byte untuk menulis! Penting, itu bisa menghemat byte di tempat lain. dan kita semua tahu, penyeleksi css bisa berantakan.

Jadi saya kira menggunakan! Penting dapat membuat pengembang senang, dan saya pikir itu sangat penting : D

xtrahelp.com
sumber
1
"Jadi, kurasa! Penting sebenarnya memiliki kinerja yang lebih baik karena dapat membantu parser melewati banyak properti yang tidak akan dilewati sebaliknya." Pernyataan ini segera dibatalkan setelah Anda memiliki beberapa !importantdeklarasi. Peramban harus memeriksa semuanya. Jadi kembali ke langkah 1, sungguh.
BoltClock
1
@BoltClock parser harus memeriksa properti terlepas dari berapa kali Anda menggunakannya ... jadi jika Anda memiliki 10 properti, parser harus melakukan pengecekan 10 kali terlepas dari apakah properti tersebut penting atau tidak. jadi jika Anda memiliki 10 properti penting, parser membuat cek 10 kali, dan jika Anda memiliki 10 properti penting, parser masih membuat cek 10 kali ... masuk akal?
xtrahelp.com
Masih tidak yakin apakah! Penting adalah peningkatan kinerja atau tidak, sungguh ... tapi saya benar-benar menikmati semua komentar dan diskusi. Pengetahuan saya mengambil langkah selanjutnya. StackOverflow luar biasa: D
Anmol Saraf
4

Saya tidak bisa meramalkan !importantkinerja yang menghambat, tidak secara inheren. Namun, jika CSS Anda penuh teka-teki !important, itu menunjukkan bahwa Anda telah memilih penyeleksi yang berlebihan dan terlalu spesifik dan Anda kehabisan orang tua, atau kualifikasi untuk menambah kekhususan. Akibatnya, CSS Anda akan menjadi kembung (yang akan menghambat kinerja) dan sulit untuk dipertahankan.

Meme aturan CSS penting

Jika Anda ingin menulis CSS efisien maka Anda ingin menjadi hanya sespesifik Anda perlu dan menulis CSS modular . Dianjurkan untuk menahan diri dari menggunakan ID (dengan hash), selektor rantai, atau penyeleksi yang memenuhi syarat.

ID yang diawali dengan #dalam CSS sangat spesifik, ke titik di mana 255 kelas tidak akan mengesampingkan id (mengutak-atik: @Faust ). Namun, ID memiliki masalah perutean yang lebih dalam, mereka harus unik, ini berarti Anda tidak dapat menggunakannya kembali untuk gaya duplikat, sehingga Anda akhirnya menulis css linear dengan gaya berulang. Dampak dari melakukan ini akan bervariasi dari proyek ke proyek, tergantung pada skala, tetapi pemeliharaan akan sangat menderita dan dalam kasus-kasus tepi, kinerja juga.

Bagaimana Anda dapat menambahkan spesifisitas tanpa !important, rantai, kualifikasi, atau ID (yaitu #)

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

Oke, jadi bagaimana cara kerjanya?

Contoh pertama dan kedua bekerja sama, yang pertama secara harfiah kelas, dan yang kedua adalah pemilih atribut. Penyeleksi Kelas dan Atribut memiliki spesifisitas yang identik. .eg1/2-bartidak mewarisi warnanya .eg1/2-fookarena memiliki aturannya sendiri.

Contoh ketiga terlihat seperti penyeleksi kualifikasi atau rantai, tetapi tidak. Rantai adalah saat Anda mengawali penyeleksi dengan orang tua, leluhur, dan sebagainya; ini menambah kekhususan. Kualifikasi serupa, tetapi Anda menentukan elemen yang diterapkan pemilih. kualifikasi: ul.classdan rantai:ul .class

Saya tidak yakin apa yang Anda sebut teknik ini, tetapi perilaku disengaja dan didokumentasikan oleh W3C

Kejadian berulang dari pemilih sederhana yang sama diperbolehkan dan meningkatkan spesifisitas.

Apa yang terjadi ketika kekhususan antara dua aturan itu identik?

Seperti yang ditunjukkan oleh @BoltClock , Jika ada beberapa deklarasi penting, maka spek menentukan bahwa yang paling spesifik harus diutamakan.

Dalam contoh di bawah ini, keduanya .foodan .barmemiliki spesifisitas yang identik, sehingga perilaku mundur ke sifat cascading CSS, di mana aturan terakhir yang dinyatakan dalam klaim CSS diutamakan yaitu .foo.

HTML

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

CSS

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

JSFiddle

Jack Tuck
sumber