盡管css選擇器效率問題已經(jīng)不是什么新鮮問題,但是我覺得還是有必要拿出來認(rèn)真分析一下。之前只是看到別人這么寫我也跟著這么寫,并沒有想清楚問什么要這樣寫?這樣寫真的能提高頁面渲染效率嗎?盡管自己技術(shù)不怎么樣,但還是需要拿出一種打破砂鍋問到底的決心來深究一下css選擇器效率問題,通過自己寫個demo親自實踐來加深一下對這個問題的理解。
事情的經(jīng)過是這樣子的,在之前的博文CSS選擇器總結(jié)中介紹了各種不同的css選擇器,頓時覺得css的世界很精彩,可以有很多種不同的寫法,想怎么寫就怎么寫,于是就有了這種代碼
.wrapperullia{color:red;……}.wrapper.listp.name{margin:10px0;……}*{margin:0;padding:0}……
寫完這樣樣式后,自我感覺還不錯,至少頁面能呈現(xiàn)出來。可是直到有一天突然發(fā)現(xiàn)
CSS選擇器從右向左的匹配規(guī)則
我的世界瞬間崩塌了,因為根據(jù)閱讀習(xí)慣在編寫CSS的時候也會自然而然是從左向右逐漸細(xì)化。頓時很想搞清楚瀏覽器在將DOM tree變成render tree的時候css規(guī)則是如何匹配的?于是查了這么些資料:
Why do browsers match CSS selectors from right to left?
Writing Efficient CSS: Understand Your Selectors
看了這么多我的理解是從右往左匹配會首先過濾掉一大批不符合規(guī)則的樣式,從而使得效率更高。舉個例子
.wrapper.lista.demo{……}
如果從左往右匹配會先找到.wrapper,然后再找到里面很多的.list,在往里找直到找到那個.demo,查找的越深,過濾掉的也就越多,在這個查找的過程中會有很多沒用的樣式也被遍歷過,這里就導(dǎo)致匹配的效率很低。
如果從右向左匹配會首先過濾掉不是.demo的元素,在依次往上查找,越往上過濾掉的也就越少,這樣效率明顯比從左往右匹配要高很多
弄明白了從右向左匹配的規(guī)則那么我們要如何寫才能讓瀏覽器更快的匹配到呢?
瀏覽器在面對眾多的CSS樣式代碼時并不是毫無規(guī)則的一個一個匹配,而是先將樣式規(guī)則分為四個主要類別:
ID 規(guī)則 這第一個類別包含了那些將 ID 選擇器作為關(guān)鍵選擇器的規(guī)則。
Class 規(guī)則 如果一個規(guī)則將一個 class 明確作為它的關(guān)鍵選擇器,那么它就屬于該類別。
標(biāo)簽規(guī)則 如果一條規(guī)則將一個標(biāo)簽作為它的關(guān)鍵選擇器,那么這條規(guī)則就屬于該類別。
通用規(guī)則 不屬于上面那些類別的規(guī)則都屬于這個類別。
并引入關(guān)鍵選擇器的概念(選擇器最后的那部分)
.wrapperullia{color:red;……}/* 關(guān)鍵選擇器為a */.wrapper.listp.name{margin:10px0;……}/* 關(guān)鍵選擇器為.name */
根據(jù)關(guān)鍵選擇器屬于哪類再在這一類中查找,從而達(dá)到更快匹配的目的。那么問題來了,怎樣寫才能達(dá)到高效呢?
CSS選擇器效率從高到低的排序如下:
ID選擇器 比如#header
類選擇器 比如.promo
元素選擇器 比如 div
兄弟選擇器 比如 h2 + p
子選擇器 比如 li > ul
后代選擇器 比如 ul a 7. 通用選擇器 比如 *
屬性選擇器 比如 type = “text”
偽類/偽元素選擇器 比如 a:hover
以上引用自Steve Souders的Even Faster網(wǎng)站
在實際使用中我們盡量選擇高效一點的選擇器,但是有一點很難避免那就是組合選擇器的使用,一般都會用到。在使用組合選擇器時我們需要注意一下幾點:
如果規(guī)則擁有ID選擇器作為其關(guān)鍵選擇器,則不在需要添加其他規(guī)則了,因為ID是唯一的。
差 .wrapper button#backButton {…}
好 #backButton {…}
不要用標(biāo)簽名限定 class 規(guī)則,這會有損靈活性
差 .wrapper p.name{…}
好 .wrapper .name{…}
避免使用過度限制選擇器(最好不要超過3層)
差 body .wrapper .content .list {}
好 .content .list{}
避免后代選擇器,后代選擇器是 CSS 中性能耗用最大的選擇器。
差 ul li a{}
好 .list .list-content{}
依賴?yán)^承
本來想寫幾個demo展示出不同選擇器的效率的,但是不好演示,大家可以看看CSS selector performance
這篇文章中介紹了20中不同的選擇器的執(zhí)行效率問題。
結(jié)合自己的實踐經(jīng)歷,在編寫CSS規(guī)則時需注意以下幾點:
嵌套層級最好不要超過3層
避免使用標(biāo)簽選擇器,盡可能使用具體的類名
不要給關(guān)鍵選擇器添加多余的規(guī)則
CSS選擇器在性能提升上盡管相對于js等提升空間不大,但在大型項目中高效率的css選擇器的性能優(yōu)勢就能得到展現(xiàn)
原文鏈接:http://www.cnblogs.com/jesse131/p/6135773.html