搭建Python爬取菠菜程式開發網頁搭建網站程式設計篇-CSS效能優化的幾個新認知

coutuixixia發表於2022-03-21

沒事喜歡利用Python對菠菜演示頁 caichen點cc進行資料抓取,今天就和大家一起聊聊我在搭建BC爬取資料時候對菠菜頁面CSS效能優化的幾個技術理解。


對於網站來說,效能顯的越來越重要了,CSS作為頁面渲染和內容展現的重要環節,影響著使用者對整個網站的第一體驗。所以,我們需要重視與CSS相關的效能優化。


專案開發初期我們可能因為各種原因(很大一部分原因是因為專案工期,產品往往把專案上線時間卡的死死的,根本不聽你說的什麼效能優化),怎麼寫的舒服就怎麼來,對於效能優化我們常常在專案完成時才去考慮,經常被推遲到專案的末期,甚至到暴露出嚴重的效能問題時才進行效能優化。

為了更多地避免這一情況,首先要重視起效能優化相關的工作,將其貫穿到整個產品設計與開發中。其次,就是了解效能相關的內容,在專案開發過程中,自然而然地進行效能優化。


css渲染規則


想要優化CSS的效能,我們首先需要了解CSS的渲染規則,CSS選擇器是從右向左進行匹配的

來看個例子:

.nav h3 a{font-size: 14px;}

渲染過程大概是:首先找到所有的a,沿著a的父元素查詢h3,然後再沿著h3,查詢.nav。中途找到了符合匹配規則的節點就加入結果集。如果找到根元素html都沒有匹配,則不再遍歷這條路徑,從下一個a開始重複這個查詢匹配(只要頁面上有多個最右節點為a)。

Tips:為什麼CSS選擇器是從右向左匹配的?

CSS中更多的選擇器是不會匹配的,所以在考慮效能問題時,需要考慮的是如何在選擇器不匹配時提升效率。從右向左匹配就是為了達成這一目的的,通過這一策略能夠使得CSS選擇器在不匹配的時候效率更高。這樣想來,在匹配時多耗費一些效能也能夠想的通了。

內聯首屏關鍵CSS(Critical CSS)

效能優化中有一個重要的指標——首次有效繪製(First Meaningful Paint,簡稱FMP)即指頁面的首要內容(primary content)出現在螢幕上的時間。這一指標影響使用者看到頁面前所需等待的時間,而 內聯首屏關鍵CSS(即Critical CSS,可以稱之為首屏關鍵CSS) 能減少這一時間。

很多人都喜歡通過link標籤引用外部CSS檔案。但需要知道的是,將CSS直接內聯到HTML文件中能使CSS更快速地下載。而使用外部CSS檔案時,需要在HTML文件下載完成後才知道所要引用的CSS檔案,然後才下載它們。所以說,內聯CSS能夠使瀏覽器開始頁面渲染的時間提前,因為在HTML下載完成之後就能渲染了。

但是我們不應該將所有的CSS都內聯在HTML文件中,因為[初始擁塞視窗]存在限制(TCP相關概念,通常是 14.6kB,壓縮後大小),如果內聯CSS後的檔案超出了這一限制,系統就需要在伺服器和瀏覽器之間進行更多次的往返,這樣並不能提前頁面渲染時間。因此,我們應當只將渲染首屏內容所需的關鍵CSS內聯到HTML中。


還有一點需要注意的是內聯CSS沒有快取,每次都會隨HTML的載入而重新下載,但我們將內聯首屏關鍵CSS控制在14.6kB以內,它對效能優化還是起到正向作用的。(凡事有利也有弊)

非同步載入非首屏CSS

我們需要知道兩點內容:(具體可以看我之前的文章:這些瀏覽器面試題,看看你能回答幾個?)

CSS不會阻塞DOM的解析,但會阻塞DOM的渲染

CSS會阻塞JS執行,但不會阻塞JS檔案的下載

由於CSS會阻塞DOM的渲染,所以我們將首屏關鍵CSS內聯後,剩餘的非首屏CSS內容可以使用外部CSS,並且非同步載入,防止非首屏CSS內容阻塞頁面的渲染。

CSS非同步載入方式

第一種方法是動態建立

// 建立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屬性設定為使用者瀏覽器不匹配的媒體型別(或媒體查詢)

對瀏覽器來說,如果樣式表不適用於當前媒體型別,其優先順序會被放低,會在不阻塞頁面渲染的情況下再進行下載。在首屏檔案載入完成之後,將media的值設為screen或all,從而讓瀏覽器開始解析CSS。

<link rel="stylesheet" href="mystyles.css" media="noexist" >

第三種方法是通過rel屬性將link元素標記為alternate可選樣式表

<link rel="alternate stylesheet" href="mystyles.css" >

第四種方法是使用rel=preload來非同步載入CSS

<link rel="preload" href="mystyles.css" as="style" >

注意,as是必須的。忽略as屬性,或者錯誤的as屬性會使preload等同於XHR請求,瀏覽器不知道載入的是什麼內容,因此此類資源載入優先順序會非常低。as的可選值可以參考上述標準文件。

看起來,rel="preload"的用法和上面兩種沒什麼區別,都是通過更改某些屬性,使得瀏覽器非同步載入CSS檔案但不解析,直到載入完成並將修改還原,然後開始解析。

但是它們之間其實有一個很重要的不同點,那就是使用preload,比使用不匹配的media方法能夠更早地開始載入CSS。所以儘管這一標準的支援度還不完善,仍建議優先使用該方法。

CSS檔案壓縮


這應該是最容易想到的一個方法了,通過壓縮CSS檔案大小來提高頁面載入速度。現在的構建工具,如webpack、gulp/grunt、rollup等也都支援CSS壓縮功能。壓縮後的檔案能夠明顯減小,可以大大降低了瀏覽器的載入時間。

CSS層級巢狀最好不要超過3層

一般情況下,元素的巢狀層級不能超過3級,過度的巢狀會導致程式碼變得臃腫,沉餘,複雜。導致css檔案體積變大,造成效能浪費,影響渲染的速度!而且過於依賴HTML文件結構。這樣的css樣式,維護起來,極度麻煩,如果以後要修改樣式,可能要使用!important覆蓋。儘量保持簡單,不要使用巢狀過多過於複雜的選擇器。

刪除無用CSS程式碼


一般情況下,會存在這兩種無用的CSS程式碼:一種是不同元素或者其他情況下的重複程式碼,一種是整個頁面內沒有生效的CSS程式碼。

對於前者,在編寫的程式碼時候,我們應該儘可能地提取公共類,減少重複。對於後者,在不同開發者進行程式碼維護的過程中,總會產生不再使用的CSS的程式碼,當然一個人編寫時也有可能出現這一問題。而這些無用的CSS程式碼不僅會增加瀏覽器的下載量,還會增加瀏覽器的解析時間,這對效能來說是很大的消耗。所以我們需要找到並去除這些無用程式碼。

那麼我們如何知道哪些CSS程式碼是無用程式碼呢?

谷歌的Chrome瀏覽器就有這種開箱即用的功能。只需轉到檢視>開發人員>開發人員工具,並在最近的版本中開啟Sources選項卡,然後開啟命令選單。然後,點選Coverage,在Coverage analysis視窗中高亮顯示當前頁面上未使用的程式碼。

unused-css.png

慎用*萬用字元


我們有時候可能會寫下面這種程式碼來消除一些標籤的預設樣式或統一瀏覽器對標籤渲染的差異化:

*{

margin:0;

padding:0;

}

這樣雖然程式碼量少,但它的效能可不是最佳的,我們最好還是寫對應的標籤選擇器:

body,dl,dd,h1,h2,h3,h4,h5,h6,p,form,ol,ul{

margin:0;

padding:0;

}

開發時儘量避免使用萬用字元選擇器

小圖片處理方式

一般來講一個網站上肯定會有很多個小圖示,對於這些小圖示,目前的主流的解決方案有三個,cssSprite(雪碧圖),字型圖示,把圖片轉成base64。

cssSprite: 把所有icon圖片合成一張png圖片,使用時對節點設定寬高,加上bacgroud-position進行背景定位。以背景圖方式顯展示需要的icon,如果一個網站有20圖示,那麼就要請求20次,使用cssSprite,只需要請求一次,大大的減少了http請求。缺點就是管理不靈活,如果需要新增一個圖示,都需要改合併圖片的原始檔,圖示定位也要規範,不然容易干擾圖片之間的定位。

字型圖示: 簡單粗暴的理解就是把所有的圖示當成一個字型處理!這樣不用去請求圖片。一般是使用class來定義圖示,要替換圖示時,只需更換樣式名,管理方便,語意明確,靈活放大縮小,並且不會造成失真。但是隻支援單色的圖片。

base64: 另一種方案就是把小的icon圖片轉成base64編碼,這樣可以不用去請求圖片,把base64編碼直接整合到js或者css裡面,可以防止因為一些相對路徑,或者圖片被不小刪除了等問題導致圖片404錯誤。但是找個方式會生成一大串的base64編碼。一般來說,8K以下的圖片才轉換成base64編碼。如果把一張50K的圖片轉成base64編碼,那麼會生成超過65000個字元的base64編碼,字元的大小就已經是將近70K了!


建議就是:8K以下的圖片才轉換成base64編碼。圖層能夠阻⽌該節點的渲染⾏為影響別的節點。⽐如對於video標籤來說,瀏覽器會⾃動將該節點變為圖層。

-----------------------------------

來自51CTO部落格作者BC搭建程式設計師詹菠的原創作品

搭建Python爬取菠菜程式開發網頁搭建網站技術篇-CSS效能優化的幾個新認知


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69920392/viewspace-2880219/,如需轉載,請註明出處,否則將追究法律責任。

相關文章