通過 Chrome 開發者工具的 Lighthouse 工具對目標站點的某個頁面進行分析,其生成的報告如圖所示:
由分析報告可知,該目標站點存在多項待優化的效能問題,如減少未使用的 JavaScript 和採用高效的快取策略提供靜態資源等問題,本文主要分析並解決採用高效的快取策略提供靜態資源問題。
Lighthouse 會標記所有未被快取的靜態資源:
Lighthouse 認為一個資源是可快取的,當且僅當以下所有條件都滿足:
當頁面未通過審計時,Lighthouse 會將結果列在一個具有三列的表格中:
列名 | 說明 |
---|---|
網址 | 可快取資源的位置 |
快取 TTL | 資源當前的快取持續時間 |
傳輸檔案大小 | 如果被標記的資源已經被快取,使用者可以節省多少資料的估算值 |
通過分析 Lighthouse 工具對目標站點生成的檢測報告,發現採用高效的快取策略提供靜態資源這一項中的快取 TTL 列,有一些靜態資原始檔的值為 None,也就是說該目標站點有部分靜態資源未被快取,那麼這部分資源在重複存取時,會重複向伺服器傳送請求,因此該情況將明顯影響目標站點效能。
為了使靜態資源快取,需要在伺服器端設定 HTTP 響應檔頭。檔頭控制瀏覽器快取的行為。以下是一些有關快取的重要檔頭:
請設定你的伺服器返回 Cache-Control HTTP 響應頭:
Cache-Control: max-age=31536000
max-age 引數告訴瀏覽器它應該將資源快取多長時間,單位為秒。以下範例將持續時間設定為 31536000,對應於 1 年:60 秒 × 60 分鐘 × 24 小時 × 365 天= 31536000 秒。
以在 Nginx 中設定 Cache-Control 響應頭為例:
http {
server {
location / {
root /html;
index index.html index.htm;
# # 設定快取時間為 1 天
# expires 1d;
# 開啟快取,並設定一年的快取期
add_header Cache-Control "public,max-age=31536000";
}
}
}
可以通過設定 expires 引數和 Cache-Control 的 max-age 來指定快取期。
add_header Cache-Control "public,max-age=31536000";
開啟了快取,並指定了快取型別為 public,表示響應可以被使用者端和代理伺服器快取,max-age 指定了資源的快取期為 31536000 秒。
Nginx 伺服器端設定 Cache-Control
響應頭後,存取靜態資源的響應如圖所示:
需要注意的是,長時間的快取期存在一個問題:使用者可能看不到靜態檔案的更新。但是可以通過設定構建工具來解決該問題,在靜態資原始檔名中嵌入雜湊來避免這個問題,以便每個版本都是唯一的,從而促使瀏覽器從伺服器獲取新版本。(要了解如何使用 webpack 嵌入雜湊,請參閱 webpack 的快取指南。)
如果資源經常更新且實時性很重要,那麼可以將其快取設定為 no-cache,但瀏覽器仍會快取該資源,不過首先會與伺服器進行檢查,以確保資源仍然是最新的。
此外,並不是快取期越長越好。而是需要根據實際需求進行權衡,以決定資源的最佳快取期。
通過在 Nginx 開啟快取,並設定合適的快取期,目標站點的效能檢測報告如圖所示:
由上圖可知,效能評分並沒有改變,但在診斷結果下已沒有採用高效的快取策略提供靜態資源這一項,這一項已經被移入已通過的稽核,也就是該項通過在伺服器設定 Cache-Control 的方式得到了效能上的優化。