CSS和網路效能

陳田田發表於2018-11-23

CSS和網路效能

CSS對於呈現頁面至關重要 - 在找到、下載和解析所有CSS之前,瀏覽器不會開始呈現 - 因此我們必須儘可能快地將其放到使用者的裝置上。關鍵路徑上的任何延遲都會影響我們的“開始渲染”,並讓使用者看到空白螢幕。

什麼是大問題?

從廣義上講,這就是CSS對效能至關重要的原因:

  1. 瀏覽器在構建渲染樹之前無法渲染頁面;
  2. 渲染樹是DOM和CSS組合結果;
  3. DOM是HTML加上需要對其進行操作的JavaScript; DOM是HTML加上需要對其進行操作的JavaScript;
  4. CSS是針對DOM應用的所有CSS規則; CSS是針對DOM應用的所有CSS規則;
  5. 使用async和defer 屬性很容易使JavaScript無阻塞;使用async和defer 屬性很容易使JavaScript無阻塞;
  6. 使CSS非同步變得困難得多;使CSS非同步變得困難得多;
  7. 所以要注意的一個好的經驗法則是,頁面只會像最慢的樣式表一樣快速地呈現。

考慮到這一點,我們需要儘快構建DOM和CSS。在大多數情況下,構建DOM相對較快:第一個HTML響應是 DOM。但是,由於CSS幾乎總是HTML的子資源,因此構建CSS通常需要更長的時間。 在這篇文章中,我們主要來看看如何證明CSS在網路上是一個重要的瓶頸(本身和其他資源),以及我們如何減輕它,從而縮短關鍵路徑並縮短開始渲染的時間。

使用關鍵CSS

如果你有能力,減少Start Render時間的最有效方法之一是使用Critical CSS模式:識別Start Render所需的所有樣式(通常是首頁上所有內容所需的樣式),將它們內聯到文件的< style >標記中< head >,並從關鍵路徑非同步載入剩餘的樣式表。 雖然這種策略是有效的,但並不簡單:高度動態的網站很難從中提取樣式; 這個過程需要自動化; 我們必須對所有的內容做出假設; 抓住邊緣情況很難; 工具仍處於相對初期階段。如果正在使用大型或遺留程式碼庫,事情變得更加困難......

拆分媒體型別

因此,如果實現關鍵CSS非常棘手 - 它可能是另一種選擇,我們將主要的CSS檔案拆分為其各自的媒體查詢。這樣做的實際結果是瀏覽器會......

  • 以非常高的優先順序下載當前上下文所需的任何CSS(中等,螢幕大小,解析度,方向等),阻止關鍵路徑;
  • 以非常低的優先順序下載當前上下文不需要的任何CSS,完全脫離關鍵路徑。

基本上,瀏覽器有效地延遲了不需要渲染當前檢視的任何CSS。

<link rel="stylesheet" href="all.css" />
複製程式碼

如果我們將所有CSS捆綁到一個檔案中,這就是網路對待它的方式:

在這裡插入圖片描述
請注意,單個CSS檔案具有最高優先順序。 如果我們可以將單個全渲染阻塞檔案拆分為各自的媒體查詢:

<link rel="stylesheet" href="all.css" media="all" />
<link rel="stylesheet" href="small.css" media="(min-width: 20em)" />
<link rel="stylesheet" href="medium.css" media="(min-width: 64em)" />
<link rel="stylesheet" href="large.css" media="(min-width: 90em)" />
<link rel="stylesheet" href="extra-large.css" media="(min-width: 120em)" />
<link rel="stylesheet" href="print.css" media="print" />
複製程式碼

然後我們看到網路以不同方式處理檔案:

在這裡插入圖片描述
不需要渲染當前上下文的CSS檔案被賦予最低優先順序。 瀏覽器仍將下載所有CSS檔案,但它只會阻止渲染完成當前上下文所需的檔案。

避免@import在CSS檔案中

我們可以做的下一件事就是幫助Start Render更加簡單。避免@import在CSS檔案中使用。 @import,憑藉它的工作原理,它很慢。對於Start Render效能來說真的非常糟糕。這是因為我們正在關鍵路徑上積極建立更多往返:

  1. 下載HTML;
  2. HTML請求CSS;
  3. CSS請求更多CSS;
  4. 構建渲染樹。

給出以下HTML:

<link rel="stylesheet" href="all.css" />
複製程式碼

all.css是:

@import url(imported.css);
複製程式碼

我們最終得到了這樣的瀑布:

在這裡插入圖片描述
明確缺乏關鍵路徑上的並行化。 通過簡單地將其展平為兩個< link rel="stylesheet" />零和零 @import:

<link rel="stylesheet" href="all.css" />
<link rel="stylesheet" href="imported.css" />
複製程式碼

我們得到一個更健康的瀑布:

在這裡插入圖片描述
開始並行化我們的關鍵路徑CSS。 如果你無法訪問包含@import (意味著你無法刪除)的CSS檔案,你可以放心地將其保留在CSS中,但也可以使用< link rel="stylesheet" /> HTML中的相應內容對其進行補充。這意味著瀏覽器將從HTML啟動匯入的CSS下載,並將跳過@import:你將不會獲得任何雙重下載。

相關文章