在Mozilla UI中最佳化CSS檔案的規則

來源:互聯網
上載者:User

原文地址:Writing Efficient CSS for use in the Mozilla UI

以下文檔描述了應用在 Mozilla UI 中最佳化 CSS 檔案的規則。第一部分是對於 Mozilla 樣式系統分類規則的一般性討論。在瞭解這個系統的基礎上,後續部分包含了一些指南,書寫可以利用這個樣式系統實踐優點的樣式的指南。

樣式系統如何分類規則

樣式系統把規則分為四大類。理解這些類是很重要的,因為對於規則的匹配來說他們是首先要考慮的。之後的段落中會使用“主選擇符”這個說法。主選擇符是指選擇符最右邊的部分(最終要匹配的那個元素,而不是它的祖先元素)。例如,在以下規則中:

a img, div > p, h1 + [title] {}

主選擇符是 “img”, “p”, 和 “[title]“。

ID 規則

ID 選擇符作為主選擇符的規則。

例如:

  • button#backButton { } /* ID 類別的規則 */
  • #urlBar[type="autocomplete"] { } /* ID 類別的規則 */
  • treeitem > treerow > treecell#myCell:active { } /* ID 類別的規則 */

Class 規則

如果一條規則有一個指定的 class 作為主選擇符,就被歸入此類。

例如:

  • button.toolbarButton { } /* 基於 class 的規則 */
  • .fancyText { } /* 基於 class 的規則 */
  • menuitem > .menu-left[checked="true"] { } /* 基於 class 的規則 */

Tag 規則

如果主選擇符不是 ID 或者 class,那麼下一個類很可能就是 tag 分類。如果一條規則指定 tag 為主選擇符,就被歸入此類。

例如:

  • td { } /* 基於 tag 的規則 */
  • treeitem > treerow { } /* 基於 tag 的規則 */
  • input[type="checkbox"] { } /* 基於 tag 的規則 */

全域規則

除以上分類之外都歸入此類。

例如:

  • [hidden="true"] { } /* 全域規則 */
  • *{} /* 全域規則 */
  • tree > [collapsed="true"] { } /* 全域規則 */

樣式系統如何匹配規則

樣式系統從最右邊的選擇符開始向左側移動來匹配一條規則。樣式系統會一直向左匹配選擇符直到規則匹配完畢或者由於出錯停止匹配。

對於規則分類的第一步發生在主選擇符類別基礎上。這個分類的目的是把那些不需要浪費時間匹配的規則過濾出來。這是顯著提升效能的重點。對於一個給定的需要匹配的元素,規則越少,樣式的渲染越快。例如,元素有一個 ID,那麼只有和元素 ID 匹配的 ID 規則會被檢索。只有和元素的 class 匹配的 class 規則會被檢索。只有和 tag 匹配的 tag 規則會被檢索。全域規則總是會被檢索。

高效 CSS 指南

避免全域規則

確保規則不以全域分類結束

不要給 ID 分類規則指定標籤名或者 class

如果有一條樣式規則是以 ID 選擇符為主選擇符的,就別再畫蛇添足的加上標籤名了。ID 都是唯一的,因此加上標籤名反而會無謂地拖慢匹配過程。(當有不同元素使用同一類名,而又需要動態地改變其中一個元素的類名來針對不同情況應用不同樣式時是個例外。)

  • BAD – button#backButton { }
  • BAD – .menu-left#newMenuIcon { }
  • GOOD – #backButton { }
  • GOOD – #newMenuIcon { }

不要給 class 分類規則指定標籤名

和以上規則類似,所有的類名也是唯一的。標籤和類名連綴的寫法是一個慣例(但是,如果設計的變更使得需要改變標籤就會有靈活性的問題,因為也需要改變 class — 最好選用具有嚴格語義的名字,這種靈活性也是分離樣式表的目標之一)。

  • BAD – treecell.indented { }
  • GOOD – .treecell-indented { }
  • BEST – .hierarchy-deep { }

盡量把規則應用到最明確的類上。

拖慢系統最大的一個原因是有太多的 tag 分類規則了。通過給元素增加類名,可以把這些 tag 類裡的規則分一部分去class 分類,就可以不需要浪費時間來試圖給一個標籤匹配那麼多的的規則了。

  • BAD – treeitem[mailfolder="true"] > treerow > treecell { }
  • GOOD – .treecell-mailfolder { }

避免後代選擇符

CSS 中,後代選擇符(descendant)[注1]的耗能高的可怕,尤其是選擇符的規則是在 tag 或者全域分類中。子選擇符(child selector)則經常是真正所需。如果沒有主題模組所有者的明確允許,UI CSS 中禁止使用後代選擇符。

  • BAD – treehead treerow treecell { }
  • BETTER, BUT STILL BAD (see next guideline) – treehead > treerow > treecell { }

Tag 類規則中最好不要包含後代選擇符

避免使用具有 tag 類規則的後代選擇符。這會明顯地增加匹配時間(尤其是這些規則會被多次匹配時)。

  • BAD – treehead > treerow > treecell { }
  • BEST – .treecell-header { }

小心子選擇符的使用

要小心使用子代選擇符。如果有別的方式可以不用,就不要用子選擇符。尤其是子選擇符被大量使用在 RDF 樹和類似的菜單中時。

  • BAD – treeitem[IsImapServer="true"] > treerow > .tree-folderpane-icon { }

要注意模版中來自 RDF 的屬性是可以複製的!可以利用這一點把 RDF 屬性複製到需要改變那個屬性的子項目上。

  • GOOD – .tree-folderpane-icon[IsImapServer="true"] { }

倚賴繼承

瞭解並使用那些可以繼承的屬性。XUL widgetry[注2] 已經明確設定了,因此可以把 list-style-image 或者 font 規則應用到父級標籤上,它將滲透進匿名內容。因此就不需要浪費時間為那些匿名內容寫規則了。

  • BAD – #bookmarkMenuItem > .menu-left { list-style-image: url(blah); }
  • GOOD – #bookmarkMenuItem { list-style-image: url(blah); }

上例中,樣式化匿名內容的需求(沒有理解 list-style-image 可以繼承)導致了一條 class 類規則。其實這條規則應該屬於最明確的一類 — ID 類規則。

要記住,尤其是那些匿名內容,它們都有同樣的 class。上面那個不好的例子導致需要檢查每個菜單的表徵圖是否包含在 bookmarks 功能表項目中。這是非常可怕的高昂消耗(有很多菜單);除 bookmarks 菜單之外,這條規則不應該被其他任何菜單想檢查。

使用 -moz-image-region

把一堆圖片放到一個單獨的圖片檔案中,並用 -moz-image-region[注3] 選中會有顯著的效能提升。()

注1: 後代選擇符(descendant selector) 子選擇符(child selector) 是有區別的。單從字面來講,後代選擇符,顧名思義包括兒子、孫子、重孫子等所有後代; 子選擇符只是指兒子,就不管那幫孫子了。

注2: XUL widgetry 不清楚是啥。

注3: 貌似想法和現在說的 CSS sprites 方法差不多,要知道這可是十年前(2000年)的文章啊。 – 糖伴西紅柿



相關文章

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.