常用CSS優化總結——網絡性能與語法性能建議

在前端面試中最常見的問題就是頁面優化和緩存(貌似也是頁面優化),被問了幾次后心虛的不行,平然平時多少會用到一些,但突然問我,很難把自己知道的都說出來。頁面優化明顯不是一兩句能夠說完的,這兩天總結了一下CSS相關的優化知識,寫篇博客梳理一下,還望大家多多指教
關于CSS的優化工作主要從兩個方面著手
網絡性能:把CSS寫到字節數最少,加快下載速度,自然可以讓頁面渲染的更快一些
語法性能:同樣都能實現某些效果,但并不是所有的方式效果都相同,我們看過不少關于JavaScript方面的語法優化知識,其實CSS里面也有一些

CSS壓縮
CSS壓縮并不是什么高端的姿勢,但卻很有用,其原理很簡單,就是把我們CSS中沒用的空白符等刪去,達到縮減字符個數的目的
我們有這樣一段CSS腳本
.test{ background-color:#ffffff; background-image:url(a.jpg); }
經過壓縮后會變成這樣
.test{ background-color:#fff; background-image:url(a.jpg)}
當然高級些的壓縮工具也會幫我們優化一些語法,提供很多選項,讓我們的壓縮更有控制,之前在的公司不采用CSS壓縮,所以我沒有什么實踐經驗,自己寫東西常用的是YUI Compressor,有很多在線版的很方便
YUI Compressor
CSS Compressor
CSS drive
Clean CSS
大家有什么好的資源希望也推薦一下
gzip壓縮
Gzip是一種流行的文件壓縮算法,現在的應用十分廣泛,尤其是在Linux平臺,這個不止是對CSS,當應用Gzip壓縮到一個純文本文件時,效果是非常明顯的,大約可以減少70%以上的文件大?。ㄟ@取決于文件中的內容)。想進一步了解gzip看看維基百科
在沒有gzip壓縮的情況下,Web服務器直接把html頁面、CSS腳本、js腳本發送給瀏覽器,而支持gzip的Web服務器將把文件壓縮后再發給瀏覽器,瀏覽器(支持gzip)在本地進行解壓和解碼,并顯示原文件。這樣我們傳輸的文件字節數減少了,自然可以達到網絡性能優化的目的。gzip壓縮需要服務器的支持,所以我們需要在服務器端進行配置
在IIS上啟用Gzip壓縮(HTTP壓縮)
apache啟用gzip壓縮方法
Nginx Gzip 壓縮配置
當然除了gzip壓縮,緩存也是我們需要注意的,這和CSS優化關系不大了,在說web優化的時候再說
合寫CSS
除了壓縮的方式,我們還可以通過少寫CSS屬性來達到減少CSS字節的目的,拿個最常見的例子
.test{ background-color: #000; background-image: url(image.jpg); background-position: left top; background-repeat: no-repeat; }
我們可以改寫一下上面的CSS,達到同樣的效果
.test{ background: #000 url(image.jpg) top left no-repeat; }
在CSS中還有很多類似的屬性可以合寫
font
{font-style: oblique; font-weight: bold; font-size: 16px; font-family: Helvetica, Arial, Sans-Serif;} {font: oblique bold 16px Helvetica, Arial, Sans-Serif;}
margin/padding
{margin-top: 5px; margin-right: 10px; margin-bottom: 20px; margin-left: 15px;} {margin: 5px 10px 20px 15px;}
{padding-top: 5px; padding-right: 10px; padding-bottom: 5px; padding-left: 10px;} {padding: 5px 10px} {padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px;} {padding:5px;}
background
{background-color: #000; background-image: url(image.jpg); background-position: left top; background-repeat: no-repeat;} {background: #000 url(image.jpg) top left no-repeat;}
border
{border-width: 2px; border-style: solid; border-color: #000;} {border: 2px solid #000;}
{border-top: 2px; border-right: 5px; border-left: 10px; border-bottom: 3px;} {border: 2px 5px 10px 3px;}
另外CSS3添加的很多屬性如transform、animation相關的都可以合寫,不一一列舉,大家用的時候要注意
利用繼承
CSS的繼承機制也可以幫我們再一定程度上縮減字節數,我們知道CSS有很多屬性是可以繼承的即在父容器設置了默寫屬性,子容器會默認也使用這些屬性,因此如果我們希望全文字體尺寸是14px,大可不必為每個容器設置,只需要在body上設置就可以了。應用這個技巧,把CSS屬性在可能的情況下提到父容器是可以幫我們節省CSS字節的,順便說一下哪些屬性可以繼承
所有元素可繼承:visibility和cursor
內聯元素和塊元素可繼承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction
塊狀元素可繼承:text-indent和text-align
列表元素可繼承:list-style、list-style-type、list-style-position、list-style-image
表格元素可繼承:border-collapse
不可繼承的:display、margin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before和unicode-bidi

css中可以和不可以繼承的屬性
抽離、拆分CSS,不加載所有CSS
抽離CSS是指把一些通用的CSS放到一個文件內,而不是寫道各個頁面,這樣一次下載后,其它頁面用到的時候就可以利用緩存了,減少不必要的重復下載。
應用抽離原則,在很多時候我們把頁面通用的CSS寫到了一個文件,這樣加載一次后就可以利用緩存,但這樣做并不適合所有場景,以前我寫CSS把一些前端插件用的CSS全寫到了一個頁面,但是有時候頁面只會用一個Dialog、有的頁面只用到了一個TreeView,但卻把十多個插件的CSS都下載到了頁面,這就是問題了,所以雖然把CSS寫道一個文件可以減少http請求,但像剛才的這種情況是不應該這樣做的,對一些所有頁面都會用到的我們可以這樣做,所以我們在抽離和拆分的時候可要想好了。
CSS sprites
這個其實算不上是CSS優化,應該說是web優化用到了CSS的技巧,順便提一下,有興趣同學可以看看使用CSS sprites減少HTTP請求

網絡性能方面能想到的就暫時這么多了,希望大家幫忙指正和補充,看一些語法上的性能優化
CSS放在head中,減少repaint和reflow
相信做web的同學都知道這條建議,但為什么CSS放在頁面頂部有利于網頁優化呢?瀏覽器渲染頁面大概是這樣的,當瀏覽器從上到下一邊下載html生成DOM tree一邊根據瀏覽器默認及現有CSS生成render tree來渲染頁面,當遇到新的CSS的時候下載并結合現有CSS重新生成render tree,剛才的渲染工作就白費了,如果我們把所有CSS都放到頁面頂部,這樣就沒有重新渲染的過程了。對瀏覽器工作原理有興趣的同學可以看看神文
瀏覽器的工作原理:新式網絡瀏覽器幕后揭秘,相信會對瀏覽器工作原理有深入的認識。
類似的我們知道了這個也應該在腳本中注意盡量減少repaint和reflow,什么情況會導致這兩種情況呢
reflow:當DOM元素出現隱藏/顯示、尺寸變化、位置變化的時候都會讓瀏覽器重新渲染頁面,之前渲染工作白費了
repaint:當元素的背景顏色、邊框顏色不引起reflow的變化是會讓瀏覽器重新渲染該元素。貌似還可以接受,但如果我們在開始就定義好了,不讓瀏覽器重復工作就更好了。
不用CSS表達式
無論怎樣生成的CSS,最終我們放到頁面上得是靜態普通文本,沒有變量、計算神馬的,CSS表達式是一種動態設置CSS屬性的東東,被IE5-IE8支持,看一個大家常用的例子
body { background-color: expression((new Date()).getHours()%2?"#B8D4FF":"#F08A00"); }
這樣我們賦予了CSS類似JavaScript的功能,CSS表達式非常強大,甚至可以使用CSS表達式實現 min-width 屬性,隔行換色,模擬 :hover, :before, :after 等偽類,看起來能解決很多IE下的瀏覽器兼容性等問題,但是其帶來的副作用超出我們的想象,這條CSS規則并不是只運行一次,為了確保有效性,CSS表達式會進行頻繁的求值,當改變窗口大小,滾動頁面甚至移動鼠標都會觸發表達式進行求值,如此頻繁的求值以至于瀏覽器的性能收到嚴重的影響。據《高性能網站建設建議》中的測試其執行次數遠遠超出我們想象,感興趣同學可以進去看看,我們的建議就試盡量避免甚至不要使用CSS表達式。
不亂用CSS reset或屬性設置
在網站建設中我們經常使用一些CSS reset,達到跨瀏覽器統一的目的,但是很多時候我們的CSS reset過于臃腫,主要有兩個問題
把很多瀏覽器對元素的默認屬性有設置了一邊,比如div的padding和margin為0啊什么的,這是沒有必要的
把一些很不常用的元素的設置也寫進了CSS reset,如 ruby這樣的元素

前幾天寫了篇關于CSS reset的博客常見標簽的默認屬性值及相互作用——關于CSS reset的思考,都是一些個人認識,希望大家批評指正
避免適用通配符或隱式通配符
CSS中的代表通配符,雖然好用但使用不當這也是一個惡魔,比如
body * {padding:0;margin:0;}
我們以為這是對body的子結點都設置一些屬性,但因為CSS繼承特性的原因,頁面所有元素都會接受這個規則,對于復雜的頁面在性能上的影響還是很大的,這并不是說不能使用通配符,而是說使用的時候要注意范圍。相信這個規則大家都知道,但是有一些隱式的通配符也需要我們的注意,比如
:visible{ padding:0; }
這樣的幾乎就和通配符一樣,在使用的時候一定要注意范圍限制問題
避免層級或過度限制的CSS
估計web開發的同學都看過MDN上Writing efficient CSS或者其各種翻譯版本,文中總結了幾點在書寫CSS selector的意見,搞明白文中建議的一個前提是得知道CSS是從右到左解析的,而不是我們認為的從左到右,關于為什么這樣做肯定是因為高效,不明就里的同學可以上網搜一下相關知識。
抄襲一下文章內容
不要用標簽或 class 來限制 ID 規則這個應該是個常識,但很多同學都會誤用,寫出#test.info或者div#test這樣的選擇器,這個只能說是畫蛇添足,id已經可以唯一而且最快的定位一個元素了
不要用標簽名限制 class 規則
這個估計被誤用的更多,如div.info這樣的寫法,其實我們可以直接寫為.info,從右到左解析的原因可以知道為什么其低效,如果直接使用class不能達到目的,一般情況下應該是class設計的有問題,CSS需要重構了
盡量使用最具體的類別、避免后代選擇器、屬于標簽類別的規則
永遠不要包含子選擇器
這三條規則是想通的,因為從左到右解析關系,在CSS選擇器中后代選擇器非但沒有幫我們加快CSS查找,反而
后代選擇器是 CSS 中耗費最昂貴的選擇器。* 它的耗費是極其昂貴的—特別是當選擇器在標簽或通用類別中,作者給的建議是當使用子選擇器時要十分謹慎,能免則免。其開銷可見一斑了。
對此我們可以通過具體類別——使用單一或盡量少的class解決。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,776評論 1 92
  • 選擇qi:是表達式 標簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font,text-align,li...
    wzhiq896閱讀 1,783評論 0 2
  • 選擇qi:是表達式 標簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font,text-align,li...
    love2013閱讀 2,325評論 0 11
  • 1、垂直對齊 如果你用CSS,則你會有困惑:我該怎么垂直對齊容器中的元素?現在,利用CSS3的Transform,...
    kiddings閱讀 3,189評論 0 11
  • 一、什么是Fragment重疊?二、什么情況下會發生Fragment重疊?三、為什么會發生Fragment重疊?1...
    叛逆的青春不回頭閱讀 2,715評論 0 3