1. 程式人生 > >css選擇器以及效能開銷

css選擇器以及效能開銷

樣式系統從最右邊的選擇符開始向左進行匹配規則。只要當前選擇符的左邊還有其他選擇符,樣式系統就會繼續向左移動,直到找到和規則匹配的元素,或者因為不匹配而退出。

如果你非常在意頁面的效能那千萬別使用CSS3選擇器。實際上,在所有瀏覽器中,用 class 和 id 來渲染,比那些使用同胞,後代選擇器,子選擇器(sibling, descendant and child selectors)對頁面效能的改善更值得關注。

 網上的資料也說到了Google 資深web開發工程師Steve Souders對CSS選擇器的效率從高到低做了一個排序:

    1.id選擇器(#myid)
    2.類選擇器(.myclassname)
    3.標籤選擇器(div,h1,p)
    4.相鄰選擇器(h1+p)
    5.子選擇器(ul < li)
    6.後代選擇器(li a)
    7.萬用字元選擇器(*)
    8.屬性選擇器(a[rel="external"])
    9.偽類選擇器(a:hover,li:nth-child)
    
    我覺得這些應該是這方面比較權威的資料了,那麼就分析一下使用過程該注意的問題,特別是跟我一樣都是jquery的熱愛者,真的是要特別注意一下,下面說一下我理解的一些例子(結合jquery分析):
    1.id選擇器肯定是最快,但是不要在ID選擇器使用的同時再使用標籤或類選擇器了,這點上jquery也是一樣的。
    不要出現這樣的寫法 "div#content" 或者 "#content.text"。David Hyatt的第一段話中有說到了,樣式系統從最右邊的選擇符開始向左進行匹配規則。只要當前選擇符的左邊還有其他選擇符,樣式系統就會繼續向左移動,直到找到和規則匹配的元素,或者因為不匹配而退出。,而在html中ID是唯一的,如果真的是用了 "div#content",瀏覽器通過ID定位到了具體的元素,然後發現左側還是標籤選擇器,那麼就會繼續匹配,繼續查詢元素,這樣無疑損耗了瀏覽器的效能,影響了渲染時間。

    2.不要在類選擇器時用標籤選擇器,這點跟jquery是剛好相反的。
    不要出現這樣的寫法 "div.text",從css的效率來看,類選擇器(class)是比標籤選擇器要好,這樣的寫法只會增加了查詢的難度,如果真的是根據標籤來區分樣式的話,考慮寫不同的class。

    3.如果明確dom結構,先使用子選擇器,減少後代選擇器使用,這點跟jquery的對比沒有留意和實踐,本人認為是相反的。
    如果你的寫法是這樣 "div a",而實際上div 跟 a 是父子關係,如果合適更建議是這麼用 "div>a",這樣效率高一些,但是不是最好的方案,下面這一點的方案會更好一些。
    
    4. 使用類選擇器替代後代選擇器和子選擇器,這點上跟jquery是不一樣的。
    如果你的寫法是這樣 "div a" "div>a",雖然前面建議用子選擇器替換後代選擇器,但是這兩個的方式還是效率低,David Hyatt的第3段話:後代選擇器在CSS中是最昂貴的選擇器。貴得要命——尤其是把它和標籤或萬用字元放在一起! 毫無疑問,我們要想其他的方式來替換這種書寫方式,那麼可以考慮這樣的寫法:div對應的為".div-text" a對應的為".div-text-a",從命名上來關聯兩者,在檢視的時候邏輯也會清晰很多。

    5. 儘量使用繼承來避免寫重複的樣式,這點與jquery沒有關係了。
    你可能會這樣寫 "#text{}  #text>.span:{font-size:24px;}  #text>.a{font-size:24px;}" ,那麼可以這麼寫".text{font-size:24px;}",讓下面的繼承這個樣式。

    這些我對css選擇器的一些看法,上面沒有說到的就是萬用字元選擇器(*)和屬性選擇器,這個其實才是最消耗效能的,因為是針對所有的元素,即便是配合其他的選擇器來用也很耗效能。實際上的ID選擇器使用的機會不是很高,因為Html中的ID是唯一的,不會有很多的ID。那麼從上面的分析,可以得到這麼一個規則:儘量使用類選擇器(class),避免使用萬用字元選擇器(*)和屬性選擇器,後代選擇器和子選擇器也儘量避免。

原文來自於:http://my.oschina.net/tearlight/blog/221730