一、前言
每一個網頁都離不開css
,但是很多人又認為,css
主要是用來完成頁面佈局的,像一些細節或者優化,就不需要怎麼考慮,實際上這種想法是不正確的
作為頁面渲染和內容展現的重要環節,css
影響著使用者對整個網站的第一體驗
因此,在整個產品研發過程中,css
效能優化同樣需要貫穿全程
二、實現方式
實現方式有很多種,主要有如下:
- 內聯首屏關鍵CSS
- 非同步載入CSS
- 資源壓縮
- 合理使用選擇器
- 減少使用昂貴的屬性
- 不要使用@import
內聯首屏關鍵CSS
在開啟一個頁面,頁面首要內容出現在螢幕的時間影響著使用者的體驗,而通過內聯css
關鍵程式碼能夠使瀏覽器在下載完html
後就能立刻渲染
而如果外部引用css
程式碼,在解析html
結構過程中遇到外部css
檔案,才會開始下載css
程式碼,再渲染
所以,CSS
內聯使用使渲染時間提前
注意:但是較大的css
程式碼並不合適內聯(初始擁塞視窗、沒有快取),而其餘程式碼則採取外部引用方式
非同步載入CSS
在CSS
檔案請求、下載、解析完成之前,CSS
會阻塞渲染,瀏覽器將不會渲染任何已處理的內容
前面載入內聯程式碼後,後面的外部引用css
則沒必要阻塞瀏覽器渲染。這時候就可以採取非同步載入的方案,主要有如下:
- 使用javascript將link標籤插到head標籤最後
// 建立link標籤
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最後位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );
- 設定link標籤media屬性為noexis,瀏覽器會認為當前樣式表不適用當前型別,會在不阻塞頁面渲染的情況下再進行下載。載入完成後,將
media
的值設為screen
或all
,從而讓瀏覽器開始解析CSS
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
- 通過rel屬性將link元素標記為alternate可選樣式表,也能實現瀏覽器非同步載入。同樣別忘了載入完成之後,將rel設回stylesheet
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
資源壓縮
利用webpack
、gulp/grunt
、rollup
等模組化工具,將css
程式碼進行壓縮,使檔案變小,大大降低了瀏覽器的載入時間
合理使用選擇器
css
匹配的規則是從右往左開始匹配,例如#markdown .content h3
匹配規則如下:
- 先找到h3標籤元素
- 然後去除祖先不是.content的元素
- 最後去除祖先不是#markdown的元素
如果巢狀的層級更多,頁面中的元素更多,那麼匹配所要花費的時間代價自然更高
所以我們在編寫選擇器的時候,可以遵循以下規則:
- 不要巢狀使用過多複雜選擇器,最好不要三層以上
- 使用id選擇器就沒必要再進行巢狀
- 萬用字元和屬性選擇器效率最低,避免使用
減少使用昂貴的屬性
在頁面發生重繪的時候,昂貴屬性如box-shadow
/border-radius
/filter
/透明度/:nth-child
等,會降低瀏覽器的渲染效能
不要使用@import
css樣式檔案有兩種引入方式,一種是link
元素,另一種是@import
@import
會影響瀏覽器的並行下載,使得頁面在載入時增加額外的延遲,增添了額外的往返耗時
而且多個@import
可能會導致下載順序紊亂
比如一個css檔案index.css
包含了以下內容:@import url("reset.css")
那麼瀏覽器就必須先把index.css
下載、解析和執行後,才下載、解析和執行第二個檔案reset.css
其他
- 減少重排操作,以及減少不必要的重繪
- 瞭解哪些屬性可以繼承而來,避免對這些屬性重複編寫
- cssSprite,合成所有icon圖片,用寬高加上backgroud-position的背景圖方式顯現出我們要的icon圖,減少了http請求
- 把小的icon圖片轉成base64編碼
- CSS3動畫或者過渡儘量使用transform和opacity來實現動畫,不要使用left和top屬性
三、總結
css
實現效能的方式可以從選擇器巢狀、屬性特性、減少http
這三面考慮,同時還要注意css
程式碼的載入順序
參考文獻
- https://mp.weixin.qq.com/s/7GdzjfV-wWgUvZPCWCLRwQ