編寫高效的CSS選取器

來源:互聯網
上載者:User
文章目錄
  • 過度修飾的選取器
  • 但是
  • 更多關於高效的CSS選取器

高效的CSS已經不是一個新話題,也不是一個我非得重拾的話題,但是,它卻是自我在SKY工作以後,真正感興趣並始終關注的一個話題。

很多人或者忘記了,或者僅僅是沒有意識到,CSS可以是高效的也可能導致低能。然而,我們可以不考慮當你自認為會的太少而使用了低效的CSS這種情況。

這些規則只真正用在效能要求很高的網站上,這些網站對速度要求很高,任何一個頁面可能含有成百上千個DOM元素。但是實踐出真理,不管你是在打造下一個facebook 還是在開發一個本地的展示網頁,多學點總是好的....

CSS 選取器

CSS 選取器對我們大多數人來說並不新鮮,較基礎的選取器分別是類型(如 div),ID(如#header)和類(如.tweet)。

較不尋常的包括基礎的偽類(如:hover)和更複雜的CSS3以及 '正則'(‘regex’)選取器,比如:first-childor[class^="grid-"]。

選取器具有固有效率,引用Steve Souders的話來說,較有效到較不有效CSS選取器的順序是這樣的:

  1. ID,如#header
  2. Class, 如.promo
  3. Type, 如div
  4. Adjacent sibling, 如h2 + p
  5. Child, 如li > ul
  6. Descendant,如ul a
  7. Universal,即*
  8. Attribute, 如[type="text"]
  9. Pseudo-classes/-elements, 如a:hover

引用自Steve Souders的Even Faster網站

認識這很重要,雖然一個ID技術上更快而且表現更優,但幾乎都不這樣用。用Steve Souders的CSS測試器,我們可以發現一個 識別碼選取器 和 一個類別選取器 在再渲染速度方面差別很小。

在一台Windows機器上的Firefox6中,我獲得了關於一個簡單的類別選取器的平均再渲染資料。ID選取器給出了12.5的平均值,所以實際上它要比一個類再渲染得慢一點。

ID與類之間的速度差異幾乎是不相干的。

對一個類型(<a>)的選擇測試,相比一個類或ID給出了慢得多的再渲染。

對一個層次非常多的子孫選取器的測試給出了 大約440的數值!

通過這我們可以發現IDs/classes與types/descendants的差別非常巨大...它們自身之間的差異很細微。

注意 這些數值在不同的機器和瀏覽器變化非常大。我極力建議你自己運行一下。

 

組合選取器

你可以單獨使用一種標準選取器,如#nav,來選擇所有以"nav"為ID的元素,你也可以使用組合選取器,如#nav a,來選擇任何在ID為’nav’的元素裡面的連結元素。

現在,我們從左至右讀這個組合標籤。我們先找到#nav ,然後再找到裡面的元素。但是我們的瀏覽器不是這樣解析的,它是從右至左來解析這些組合選取器的。

當我們看到#nav裡面有個a,而瀏覽器看到的卻是有個a在 #nav裡面,這些細微的差異對瀏覽器的效能有重大影響,同事學習他們是很有價值的。

如果想知道瀏覽器這樣解析的原因,請參考this discussion on Stack Overflow.

對瀏覽器來說,從最右邊的元素(它最想渲染的元素)開始,然後回溯到DOM樹比從DOM樹的最高層開始選擇向下尋找,甚至可能達不到最右邊的選取器(關鍵的選取器)要高效。

這對CSS選取器的效能有重大影響....

 

關鍵選取器

這裡討論的關鍵選取器, 是處在複雜選取器最右端的選取器,也是瀏覽器最先解析的選取器。

讓我們回到討論開始的地方,哪種選取器最高效?哪種選取器作為關鍵選取器會影響選取器的效能;當我們書寫CSS代碼的時候,正是這個關鍵選取器影響選取器的效率。

一個關鍵選取器是這樣的:

#content.intro{}

天生高效選取器如類型選取器是不是就會有更高的效能?瀏覽器會尋找.Intro的所有執行個體(數量不會很多),然後向上尋找DOM樹,以確定該關鍵選取器是否在以“content’”為ID的元素裡面。

然後,以下的選取器效能就不怎麼好了:

#content*{}

這個選取器做的工作是這樣子的,它先尋找每個頁面(是每個單個的頁面),然後去看看它們是否有一個 #content 的父元素。這是一個非常不高效的選取器,因為它的關鍵選取器執行開銷太大了。

運用這些知識我們就能在分類和選擇元素時做更好的選擇。

 

 

假設我們有一個非常龐大的頁面,非常的大並且是一個還有一個龐大的網站。在這個也面上,有上百甚至上千哥<a>標籤。社交媒體的連結只佔很少的一部分,並且包含在ID為#social的<ul>裡面。假設這些連結是,Twitter, facebook, Dribble 和 Google+。我們在這個頁面上有四個社交媒體連結,還有上百個其他的連結。

以下這個選取器代價很高而且效能不好:

#social a{}

瀏覽器將訪問掃描頁面上的上千個連結,然後才選擇上#social節點下的四個連結。我們的關鍵選取器匹配了大量的我們並不感興趣的標籤。

為了消除這個問題,我們可以為每一個包含在社交媒體<ul>塊下面的<a>標籤指定更明確和顯式的選取器.social-link。但是這跟我們所知道的恰恰相反;我們知道了,當我們使用精簡的標籤的時候,盡量不要使用多餘的類。

 

這就是為什麼我覺得效能是如此的有意思;在網頁標準最佳實務和速度之間,需要一個平衡。

我們通常會這麼寫:

<ul id="social">    <li><a href="#" class="twitter">Twitter</a></li>    <li><a href="#" class="facebook">Facebook</a></li>    <li><a href="#" class="dribble">Dribbble</a></li>    <li><a href="#" class="gplus">Google+</a></li></ul>

CSS:

#social a{}

現在我們改為:

<ul id="social">    <li><a href="#" class="social-link twitter">Twitter</a></li>    <li><a href="#" class="social-link facebook">Facebook</a></li>    <li><a href="#" class="social-link dribble">Dribbble</a></li>    <li><a href="#" class="social-link gplus">Google+</a></li></ul>

對應的CSS:

#social .social-link{}

這是一個全新的關鍵選取器,匹配更少的元素,意味著瀏覽器可以更快地找到它們並給它們賦予樣式。

同時,實際上,我們可以進一步精簡選取器,使用.social-link{},而不需要過渡的約束它;閱讀下一章節來瞭解詳情。

所以,概括的說,你的關鍵選取器是其中一個決定瀏覽器的工作量,所以你需要好好的留意它。

 

過度修飾的選取器

現在我們已經瞭解了關鍵選取器是什麼,它是後續工作的基礎,我們現在來看看如何進一步最佳化它。使用更明確的關鍵選取器就是,你需要避免過度使用修飾選取器。以下是一個過度修飾的選取器:

1 html body .wrapper #content a{}

這個選擇太囉唆,起碼有三個選取器是完全沒必要的。精簡樣式應該為:

#content a{}

那又如何?

這意味著瀏覽器需要掃描所有的標籤,檢查它裡面是否包含一個ID叫做“content”的標籤,如此在html標籤中不停尋找。這樣會導致瀏覽器做了多餘的檢查工作,並且是完全沒必要的工作。知道了這點後,我們可以看看下面更接近實際的例子:

#nav li a{}

精簡為:

#nav a{}

我們知道如果標籤a在li標籤裡面,li標籤又在#nav裡面,那麼我們可以從選取器中去掉li。然後,因為nav擁有一個ID,這個ID是唯一的,所以它賦予的元素是完全不相干的,我們可以去掉ul。

過度修飾的選取器會導致瀏覽器需要做更多的工作;從選取器中去除不必要的部分,讓你的選取器更簡潔,效能更高吧。

所有這些都是必要的嗎?

簡短的答案是:可能不是。

長一點的答案是:它依賴於你正在建立的網站。如果你在做你的下一個作品,那麼超越CSS選取器效能去追尋乾淨的代碼吧,因為你其實並不想關注它。

如果你在建立下一版的Amazon, 而頁面速度的微秒變化確實會有不同,那麼可能需要,但即使那樣也可能不。

瀏覽器只會在CSS解析速度方面越來越好,甚至行動瀏覽器也一樣。你很可能從來也不會注意到瀏覽器中的很慢的CSS選取器,但是...

 

但是

它仍然正在發生著,不管瀏覽器有多麼快,它們仍然必須做所有我們談論到的工作。即使你不需要甚至不想實施其中任何一條,它當然仍是值得知道的東西。記得選取器可能會代價很高,還有你應該在可能的地方避免使用代價更大的選取器。那意味著,如果你發現自己寫了一些東西諸如:

div:nth-of-type(3) ul:last-child li:nth-of-type(odd) *{ font-weight:bold }

那麼可能你做得不對。現在我自己在高效選取器的世界也是一個新手,因此如果我遺漏了什麼,或者你有什麼需要添加的,請在評論裡發表它!

更多關於高效的CSS選取器

我怎麼推薦Steve Souders的網站與書也不過分。對你需要的延伸閱讀來說,那足夠了。這夥計知道的很多!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.