CSS 性能調優

簡介

  Web 開發中經常會遇到性能的問題,尤其是 Web 2.0 的應用。CSS 代碼是控制頁面顯示樣式與效果的最直接“工具”,但是在性能調優時他們通常被 Web 開發工程師所忽略,而事實上不規範的 CSS 會對頁面渲染的效率有嚴重影響,尤其是對於結構複雜的 Web 2.0 頁面,這種影響更是不可磨滅。所以,寫出規範的、高性能的 CSS 代碼會極大的提高應用程序的效率。本文主要來探討一下如何優化,以及從哪些方面優化應用程序的 CSS 代碼,從而最大限度的提高 Web 應用的性能。

 

  CSS 性能調優

  CSS 代碼的分析與渲染都是由瀏覽器來完成的,所以,瞭解瀏覽器的 CSS 工作機制對我們的優化有至關重要的作用。這篇文章我們主要從如下幾個方面入手來介紹一下 CSS 的性能優化:

  Style 標籤的相關調優

  特殊的 CSS 樣式使用方式

  CSS 縮寫

  CSS 的聲明

  CSS 選擇器

  把 Stylesheets 放在 HTML 頁面頭部:

  瀏覽器在所有的 stylesheets 加載完成之後,纔會開始渲染整個頁面,在此之前,瀏覽器不會渲染頁面裏的任何內容,頁面會一直呈現空白。這也是爲什麼要把 stylesheet 放在頭部的原因。如果放在 HTML 頁面底部,頁面渲染就不僅僅是在等待 stylesheet 的加載,還要等待 html 內容加載完成,這樣一來,用戶看到頁面的時間會更晚。

  對於 @import 和 兩種加載外部 CSS 文件的方式:@import 就相當於是把 標籤放在頁面的底部,所以從優化性能的角度看,應該儘量避免使用 @import 命令

  避免使用 CSS Expressions:

  參考下述代碼:

  清單 1. CSS Expression 案例

  1. Background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" ) 

 

 

  Expression 只有 IE 支持,而且他的執行比大多數人想象的要頻繁的多。不僅頁面渲染和改變大小 (resize) 時會執行,頁面滾動 (scroll) 時也會執行,甚至連鼠標在頁面上滑動時都會執行。在 expression 裏面加上一個計數器就會知道,expression 的執行上相當頻繁的。鼠標的滾動很容易就會使 expression 的執行次數超過 10000。

  避免使用 Filter:

  IE 特有的 AlphaImageLoader filter 是爲了解決 IE6 及以前版本不支持半透明的 PNG 圖片而存在的。但是瀏覽器在下載 filter 裏面的圖片時會“凍結”瀏覽器,停止渲染頁面。同時 filter 也會增大內存消耗。最不能忍受的是 filter 樣式在每個頁面元素(使用到該 filter 樣式)渲染時都會被瀏覽器分析一次,而不是像一般的背景圖片渲染模式:使用過該背景圖片的所有元素都是被瀏覽器一次性渲染的。

  針對這種情況,最好的解決辦法就是使用 PNG8。

  CSS 縮寫:

  CSS 縮寫可以讓你用極少的代碼定義一系列樣式屬性,這種做法可以極大程度的縮減代碼量以達到提高性能的目的。

  清單 2. Colour 縮寫

  1. #000000     ------>>     #000  
  2. #336699     ------>>     #369 

 

 

  關於顏色,重複的屬性值可以省略。

  清單 3. 各種縮寫方式

  1. Margin-top: 2px;  
  2.  Margin-right: 5px;  
  3.  Margin-bottom: 2em;  
  4.  Margin-left: 15px;     ----->>     Margin: 2px 5px 2em 15px;  
  5.  
  6.  Border-width: 1px;  
  7.  Border-style: solid;  
  8.  Border-color: #000     ----->>     border: 1px solid #000  
  9.  
  10.  Font-style: italic;  
  11.  Font-variant: small-caps;  
  12.  Font-weight: bold;  
  13.  Font-size: 1em;  
  14.  Line-height: 140%;  
  15.  Font-family: sans-serif;  ----->>  font: italic small-caps bold 1em 140% sans-serief  
  16.  
  17.  Background-color: #f00;  
  18.  Background-image: url(background.gif);  
  19.  Background-repeat: no-repeat;  
  20.  Background-attachment: fixed;  
  21.  Background-position: 0 0;  
  22.   ----->>background: #f00 url(background.gif) no-repeat fixed 0 0  
  23.  
  24.  list-style-type: square;  
  25.  list-style-position: inside;  
  26.  List-style-image: url(image.gif)  ----->> list-style: square inside url(image.gif)  

 

 

  Multiple Declarations

  關於 CSS 的 class 聲明和定義,也有簡寫的方式

  清單 4. Class 的聲明

  1. .Class1{position: absolute; left: 20px; top: 30px;}  
  2. .Class2{position: absolute; left: 20px; top: 30px;}  
  3. .Class3{position: absolute; left: 20px; top: 30px;}  
  4. .Class4{position: absolute; left: 20px; top: 30px;}  
  5. .Class5{position: absolute; left: 20px; top: 30px;}  
  6. .Class6{position: absolute; left: 20px; top: 30px;}  
  7.  
  8.  -------------------->>>>>>>  
  9.  
  10.  .class1 .class2 .class3 .class4 .class5 .class6{  
  11.  Position: absolute; left: 20px; top: 20px;  
  12.  }  

 

 

  這種 Class 簡寫的方式可以極大的縮減我們的代碼,提高瀏覽器分析識別的效率。

  CSS 選擇器 (CSS Selectors)

  先來看看下面這個例子:

  清單 5. Child selector

  1. #toc > li {font-weight: bold}  

 

 

  按照我們慣常的理解,編譯器應該是先查找 id 爲“toc”的節點,然後在他的所有直接子節點中查找類型(tag)爲“li”的節點,將“font-weight”屬性應用到這些節點上。

  但是,不幸的是,恰恰相反,瀏覽器是“從右往左”來分析 class 的,它的匹配規則是從右向左來進行匹配的。這裏,瀏覽器首先會查找頁面上所有的“li”節點,然後再去做進一步的判斷:如果它的父節點的 id 爲“toc”,則匹配成功。

  由此可知,CSS 選擇器的匹配遠比我們想象的要慢的多,CSS 的性能問題不容忽視。

  清單 6. Descendant selector

  1. #toc  li {font-weight: bold} 

 

 

  這個效率比之前的“child selector”效率更慢,而且要慢很多。瀏覽器先便利所有的“li”節點,然後步步上溯其父節點,直到 DOM 結構的根節點(document),如果有某個節點的 id 爲“toc”,則匹配成功,否則繼續查找下一個“li”節點。

  清單 7. 儘量避免 universal rules

  1. [hidden="true"] { ... } /* A universal rule */   

 

 

  這裏的匹配規則很明顯:查找頁面上的所有節點,如果有節點存在“hidden”屬性,並且其屬性值爲“true”,則匹配成功。這是最耗時耗力的匹配,頁面上的所有節點都需要進行匹配運算,這種規則應儘量避免。

  清單 8. Id-categorized 規則與 tag name 或 class 規則並行

  1. button#goButton {...};----->>#goButton  
  2. .fundation#testIcon {...};----->>#testIcon  

 

 

  這裏,按照我們常規的理解,箭頭左邊的寫法似乎是應該更快的,因爲它的限制更多。其實不然,id 是全局唯一的,在匹配 CSS 選擇器時瀏覽器定位到 id 是最快的,如果伴隨有其他的非 id 的 selector,反而會影響匹配的效率。

  清單 9. 關於 class-categorized 規則

  1. button.indented {...}----->>.button-indented {...}  

 

 

  程序員們經常會給某個 Class 前面加上標籤名稱(Tag Name),以更精確且快速的定位該節點,但是這樣往往效率更差。和清單 8 中的原理一樣,頁面上的 class 在全局範圍內來講應該是唯一的,用唯一的 Class 名稱來定位一個節點往往比組合定位更加快捷。事實上,這種做法也可以避免由於開發修改頁面元素的類型(Tag)而導致的樣式失效的情況,做到樣式與元素的分離,兩者獨立維護。

  清單 10. 儘量減少規則數量

  1. Span[mailfolder="true"> table > tr > td.columnClass {...}  
  2.  
  3. ------------------->>>>>>>  
  4.  
  5. .span-mailfolder-tbl-tdCol {...}  

 

 

  規則越多,匹配越慢,上面一種規則需要進行 6 項匹配,先找“columnClass”,再找“td”,然後是“tr”,“table”,最後是符合“mailfolder”爲“true”的 span,這種效率是非常慢的。如果用一個比較特殊的 class 替代(span-mailfolder-tbl-tdCol),效率會快上好幾倍。

  清單 11. 儘量避免使用 descendant selector

  1. treehead treerow treecell {...} ----->> treehead > treerow > treecell {...}  

 

 

  Descendant 選擇器是耗時相對高的選擇器,通常來講,它在 CSS 裏的使用應該是儘量避免的,如果能用 child 選擇器替代就應該儘量這樣去做。

  清單 12. 利用 CSS 的繼承機制

  1. Color  
  2. Font  
  3. Letter-spacing  
  4. Line-height  
  5. List-style  
  6. Text-align  
  7. Text-indent  
  8. Text-transform  
  9. White-space  
  10. Word-spacing  
  11.  
  12. #bookmark  > .menu-left {list-style-image: url(blah)}  
  13.  
  14. ------------>>>>>>>>  
  15.  
  16. #bookmark  {list-style-image: url(blah)}  

 

 

  在 CSS 中,有很多 CSS 的屬性以可以繼承的,如果某個節點的父節點已經設定了上述的 CSS 樣式(如:color, font 等 ...),並且子節點無需更改該樣式,則無需再作相關設定,同時,也可以利用這一點:如果很多子節點都需要設定該 CSS 屬性值,可以統一設定其父節點的該 CSS 屬性,這樣一來,所有的子節點再無需做額外設定,加速了 CSS 的分析效率。

 

  結束語

  這篇文章介紹了 Web 開發中關於 CSS 性能方面需要注意的一些小細節,從 CSS 本身着手,介紹了編寫 CSS 代碼中需要避免的一些寫法,比如 CSS Expression 的弊端,CSS 縮寫以及 CSS 選擇器的注意事項等等,也分享了一些比較推薦的做法。我們可以在開發過程中儘量注意一下這些小細節,以儘可能多的提高我們 Web 應用的性能。


轉自: http://www.php100.com/html/webkaifa/DIV_CSS/2011/0922/9069.html

發佈了41 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章