HTTP 快取解析:ETag、Cache-Control 與 CDN

Web2026-09-28TryQuickToolBox

為什麼你的網站感覺很慢(以及快取如何解決這個問題)

你已經優化了圖片、壓縮了 CSS,甚至升級了伺服器。但回訪者仍然體驗到緩慢的載入時間,而你的來源伺服器正在消耗大量頻寬。罪魁禍首是什麼?效率不彰的 HTTP 快取。如果沒有適當的快取標頭,瀏覽器會在每次造訪時重新下載相同的資源,而 CDN 也無法有效發揮作用。

HTTP 快取是現今最具槓桿效應的效能優化手段之一。它能降低延遲、減少頻寬成本,並減輕來源伺服器的負載。在本指南中,我們將拆解關鍵機制:ETag、Cache-Control,以及 CDN 如何融入其中。你將學到正確實作這些機制的實用策略。

HTTP 快取如何運作:整體概觀

當瀏覽器請求一個資源時,它可以從來源伺服器取得,或是提供本機儲存的副本。HTTP 快取定義了儲存的副本何時被視為新鮮,以及何時必須重新驗證的規則。

快取主要分為兩種類型:

兩者都依賴 HTTP 標頭來決定新鮮度和重新驗證。最重要的兩個標頭是 Cache-Control 和 ETag。

Cache-Control:新鮮度規則

Cache-Control 是定義快取政策的主要標頭。它是一個基於指令的標頭,告訴快取如何處理回應。

關鍵指令

範例:Cache-Control: public, max-age=31536000, immutable 是帶有雜湊檔名的靜態資源的理想設定。

ETag 與條件式請求

ETag(實體標籤)是資源特定版本的識別碼。當資源變更時,ETag 也會改變。瀏覽器使用 ETag 發出條件式請求:它們在 If-None-Match 標頭中發送儲存的 ETag。如果資源沒有改變,伺服器會回應 304 Not Modified 且不帶主體,從而節省頻寬。

同樣地,Last-Modified 與 If-Modified-Since 搭配運作,但 ETag 更精確(它們可以偵測同一秒內的變更)。

如何產生 ETag

大多數網頁伺服器和框架會自動產生 ETag。例如,在 Express.js 中,你可以用 app.set('etag', 'strong') 來啟用。在 Nginx 中,靜態檔案預設就會開啟 ETag。

強 ETag(例如 "abc123")保證位元組層級的完全相同。弱 ETag(例如 W/"abc123")表示語意上的等價,而非精確的位元組。

CDN 快取:大規模的共享快取

CDN(內容傳遞網路)扮演全球分散式共享快取的角色。它們在邊緣節點快取你的內容,從鄰近的節點提供給使用者。這能降低延遲並卸載來源伺服器的負擔。

CDN 會遵循 Cache-Control 標頭,但通常也有自己的配置。關鍵概念:

使用 CDN 時,設定 Cache-Control 並搭配 s-maxage,以獨立於瀏覽器快取來控制共享快取的新鮮度。例如:Cache-Control: public, max-age=600, s-maxage=3600 表示瀏覽器快取 10 分鐘,但 CDN 快取 1 小時。

快取標頭比較

標頭 用途 範例
Cache-Control 定義新鮮度與快取規則 public, max-age=3600
ETag 資源版本的唯一識別碼 "abc123"
Last-Modified 最後修改的時間戳記 Wed, 21 Oct 2025 07:28:00 GMT
Expires 舊式的絕對到期日期 Wed, 21 Oct 2025 07:28:00 GMT
Vary 指定會影響快取的標頭 Accept-Encoding

注意:Expires 已被 Cache-Control 取代,但較舊的用戶端仍會使用。

Web 應用程式的實用快取策略

遵循以下步驟來實作有效的快取:

  1. 為靜態資源加上指紋: 使用雜湊檔名(例如 app.a1b2c3.js),並設定較長的 max-age 與 immutable。當檔案變更時,雜湊也會改變,從而破壞快取。
  2. 為 HTML 設定適當的 Cache-Control: HTML 通常應設為 no-cache 或較短的 max-age,以便使用者快速取得更新。使用 ETag 進行重新驗證。
  3. 使用 Vary: Accept-Encoding: 如果你提供壓縮和未壓縮的版本,這能確保快取將它們分開儲存。
  4. 利用 CDN 與 s-maxage: 為共享快取設定較長的 s-maxage 以減少來源負載,同時視需要讓瀏覽器快取保持較短。
  5. 明智地失效: 部署關鍵更新時,使用 CDN 的清除 API。對於靜態資源,指紋技術可避免需要清除。
  6. 監控快取命中率: 使用 CDN 分析來確保你的快取有效。低命中率意味著標頭配置錯誤。

常見陷阱與如何避免

測試你的快取設定

使用瀏覽器 DevTools(Network 分頁)檢查回應標頭,並查看資源是否從快取提供(尋找「(from disk cache)」或「(from memory cache)」)。若要了解 CDN 行為,請使用 curl -I 檢查如 X-Cache 或 CF-Cache-Status 等標頭。像 WebPageTest 這類工具可以視覺化多次造訪之間的快取情形。

常見問題

ETag 和 Last-Modified 有什麼不同?

ETag 是不透明的識別碼,會在資源變更時改變,而 Last-Modified 是時間戳記。ETag 更精確,因為它們可以偵測同一秒內的變更,且不依賴時鐘同步。

什麼時候應該使用 no-cache 與 no-store?

當你希望快取儲存回應,但每次使用前都向來源伺服器重新驗證時,請使用 no-cache。對於絕不能被任何快取寫入磁碟或記憶體的敏感資料,請使用 no-store。

CDN 如何處理快取失效?

CDN 提供清除 API,讓你可以從邊緣快取中移除特定 URL 或整個目錄。有些也支援軟清除,將內容標記為過時,並在下次請求時重新驗證。為資源加上指紋通常比清除更有效率。

結論

精通 HTTP 快取,搭配 ETag、Cache-Control 和 CDN,是建構快速、可擴展 Web 應用程式的關鍵。從為靜態資源和 HTML 設定適當的標頭開始,利用 CDN 共享快取的 s-maxage,並始終測試你的配置。快取標頭的微小變更就能帶來顯著的效能提升。

需要快速分析伺服器日誌以查看快取命中率嗎?試試我們的 Nginx 日誌分析器 來解析並視覺化你的存取日誌。