標籤:style blog http color 使用 strong 資料 for
前面花了幾個篇幅著重介紹了CSS的選取器的使用,我將其分成三個部分:CSS3基本選取器、CSS3屬性選取器詳解以及CSS3偽類別選取器詳解。那麼今天我主要想和大家一起來學習——CSS選取器方面的效能最佳化。因為對效能這一塊一直都是很弱的,所以今天先從選取器開始入手,加強自己。如果你也感興趣那就跟我一起來吧。
瀏覽器如何識別你的選取器
首先我們需要清楚,瀏覽器是如何讀取選取器,以識別樣式,並將相應的樣式附於對應的HTML元素,達到美化頁面的效果。Chris Coyier曾在《Efficiently Rendering CSS》一文中說過“瀏覽器讀取你的選取器,遵循的原則是從選取器的右邊到左邊讀取。換句話說,瀏覽器讀取選取器的順序是由右到左進行”。比如說:
div.nav > ul li a[title]
上面的執行個體來說,瀏覽器首先會嘗試在你的HTML標籤中尋找“a[title]”元素,接著在匹配“li和ul”,最後在去匹配“div.nav”。這就是前成所主的“選取器從右至左的原則”。
選取器的最後一部分,也就是選取器的最右邊(在這個例子中就是a[title]部分)部分被稱為“關鍵選取器”,它將決定你的選取器的效率如何?是高還是低。
老版本的瀏覽器可以過濾掉不匹配的選取器,而直接匹配更高效的選取器。記得David Hyatt在《Writing efficient CSS for use in the Mozilla UI》說過:“這個關鍵選取器可以大大提高選取器的效能,少檢查一個給定的元素規則,就可以更有效將樣式匹配給對應的HTML元素。”那麼如何讓關鍵選取器更有效,效能化更高呢?其實很簡單,主要把握一點“越具體的關鍵選取器,其效能越高”
那麼什麼樣類型的選取器,其效能高?什麼樣的類型的選取器效能低呢?下面我們就針對兩個問題來展開具體的學習。
CSS選取器的效率
如果你閱讀了本站的有關於選取器類型的介紹的話,你對選取器並不會感到陌生。就算你沒讀過,我想CSS選取器不會讓我們覺得是新東西,比如我們常用的基本選取器“元素標籤選取器div”、“id選取器#header”、“類別選取器.class”,或者說我們很少見的偽類別選取器“:focus”以及更複雜的css3選取器“:nth-child”等等。
選取器有一個固有的效率,我們來看Steve Souders給排的一個順序:
- id選取器(#myid)
- 類別選取器(.myclassname)
- 標籤選取器(div,h1,p)
- 相鄰選取器(h1+p)
- 子選取器(ul > li)
- 後代選取器(li a)
- 萬用字元選取器(*)
- 屬性選取器(a[rel="external"])
- 偽類別選取器(a:hover,li:nth-child)
上面九種選取器的效率是從高到低排下來的,基中ID選取器的效率是最高,而偽類別選取器的效率則是最底。詳細的介紹大家還可以點擊Writing efficient CSS selectors。
綜合上面的順序,我們清楚的知道,id和類名用於關鍵選取器上效率是最高的,而CSS3的仿偽類和屬性選取器,雖然使用方便,但其效率卻是最低的。我們下面一起來看幾個執行個體的對比:
div #myid
效率要比下面的高:
#myid div
第一種選取器比第二種選取器效率高,大家或許會問為什嗎?其實根據前面所介紹的我們就不難理解了,因為第一個選取器的“關鍵選取器”使用了“ID選取器”,而第二個選取器的“關鍵選取器”使用的是“標籤選取器”,對比下來,“ID選取器”效率高過“標籤選取器”,所以說第一個選取器的效率要高於第二個選取器。
在類名或ID名前面加上標籤也會致使選取器效率變低的,比如說:
#myid .myclassname
上面兩個選擇的效率要高於下面的選取器:
p#myid p.myclassname
來自Mozilla的幾點建議
David在《Use efficient CSS selectors》中介紹了幾種書寫高效率的CSS選取器的方法,下面我將他們移到這裡來讓大家參考:
- 避免普遍規則
- 不要在ID選取器前加標籤名或類名
- 不要在類名選取器前加標籤名
- 儘可能使用具體的類別
- 避免使用後代選取器
- 標籤分類規則中不應該包含一個子選取器
- 子選取器的問題
- 藉助相關繼承關係
- 使用範圍內的樣式表
如果你不夠清楚上面所講的是什麼,你可以點擊這裡,他會讓你更容易瞭解這些規則。
我們應該怎麼做
前面說“ID選取器”的效率是最高的,那麼今天我們寫樣式,為了提高選取器的效率,是不是我們要在每一個文檔的HTML元素中都加入ID名呢?我想這樣的做法是沒有的。對於一個有語義的代碼編寫和如何提高效能,以前他們之間如何的平衡?其實這個選取器的效率低一點,對於大多數網站來說並不會有太大的影響,但對於一個大型的網站,產生大量的流量這就會有差別了,也就很值得我們去對他進行最佳化。那麼我們就很有必要的去瞭解他們是如何工作,比如說,一般情況下哪些選取器的使用效率更高。來看兩個簡單的例子:
#myid
上面的選取器高於下面的:
p#myid
後者的寫法我發現還是有很多朋友這樣寫,但我不知道你為什麼需要在ID前面加一個標籤?難道你同一個頁面會有多個相同的ID不成?
我們接下來在來看一個執行個體,用於列表上的,比如說我們製作導覽功能表的:
#nav a
高效於:
#nav li a
上面只是介紹了兩個常碰到的執行個體,在這裡說這兩個執行個體,主要目的是讓你在今後的編寫樣式時,能注意這方面的的細節,從而加快你的代碼效率。
測試你的選取器
Steve Souders給我們提供了一個選取器效率測試,您 可以測試不同的選取器,比較他們之間的效率。
我們一起來看一個Jon Sykes在前幾年對後代選取器效能做的測試的對比:
直接類別選取器:
.tdxx{ background: red; }
與後代選取器:
table tr td.tdxx{ background: red; }
上面兩個選取器所做的效能測試結果:
我想上面的圖表就能很清楚的說明問題所在了。(註:上面的測試是幾年前的資料;縱向是時間ms,模向前面是後代選取器,後面是直接類別選取器)。如果你對這個感興趣可以參閱:
- Testing CSS Performance
- Testing CSS Performance (pt 2)
- More CSS Performance Testing (pt 3)
上面扯了這麼多,其實就是想說,CSS的選取器對一個網站的效能也是有關係的,學習之後,希望大家在平時的編寫之時能盡量克服一些沒必要的錯誤,從而提高這方面的效能。希望這篇文章對大家有所協助。如果你有更好的建議,請隨時在評論中給我留言。
感謝W3CPLUS提供精彩原文。
歡迎大家加入互連網技術交流群:62329335