Core Web Vitals 效能優化專家
建立摘要
快取與 CDN LCP CLS INP

快取是什麼:從瀏覽器到 CDN 的暫存機制與 HTTP 控制方式

快取(Cache)是決定資源載入速度的核心機制,從瀏覽器本機快取到 CDN 邊緣節點都有它。本文從記憶體層次延遲數字說起,解釋 Cache-Control 各指令的實際行為,包括 no-cache 並非不快取這個常見誤區,以及快取命中率對 TTFB 和 LCP 的量化影響。

陳柏翰

網站效能工程師

快取是什麼:從瀏覽器到 CDN 的暫存機制與 HTTP 控制方式

快取是什麼:不只是「暫存」的暫存

快取(Cache)是一種將已取得的資料保存在取用速度更快的位置上,下次需要時直接從那裡拿,跳過重新取得的完整流程

最直接的例子:你第一次開啟某個網站,瀏覽器必須向伺服器要求 HTML、CSS、JS、圖片,每一個都是一次網路請求。但你第二次開啟同一個頁面,瀏覽器直接從本機硬碟讀出已存的檔案,不發出任何網路請求。你感覺它「變快了」,但準確的說法是:快取命中了。

這個機制存在於電腦架構的每個層次。CPU 有 L1/L2/L3 快取,OS 有記憶體頁面快取,應用程式有物件快取,瀏覽器有 HTTP 快取,CDN 有邊緣節點快取。它們的共同邏輯都一樣:在存取速度快的地方放一份副本,避免每次都回到慢的地方重拿。

CDN 快取對網頁效能最直接的影響是 LCP(Largest Contentful Paint)。關於 Cloudflare Cache Rules 設定與 cache hit rate 診斷的實戰紀錄,可以看 CDN 改善 LCP 的機制與實測

快取的兩個基本概念值得記住:

  • Temporal locality:剛用過的東西,短期內很可能再用。
  • Spatial locality:用到某個資料,它附近的資料也很快會被用到。

現代快取系統的設計邏輯幾乎都建立在這兩個觀察上。

從 1 奈秒到 100 毫秒:快取為什麼快這麼多

說快取讓東西「更快」太模糊了。具體快多少,有一組數字能說清楚。

記憶體層次延遲對比:L1快取到Origin伺服器的存取時間差異
記憶體層次延遲數字對比,從 CPU L1 快取的 1 奈秒到跨洲際 Origin 伺服器的數百毫秒
層次 存取延遲(約) 說明
L1 CPU 快取 ~1 ns 在 CPU 晶片上,最快
L2 CPU 快取 ~5 ns 略大,略慢
L3 CPU 快取 ~20 ns 多核心共用
主記憶體(RAM) ~100 ns L1 的 100 倍
SSD 讀取 ~100 μs(100,000 ns) RAM 的 1,000 倍
CDN 邊緣節點 ~10–50 ms 最近的網路快取層
Origin 伺服器 ~100–500 ms 跨洲際最慢

這組數字來自 Jonas Bonér 整理的延遲參考數據,源自 Jeff Dean 的原始研究,工程圈廣泛引用多年。數字本身不是絕對值,但量級關係是穩定的:CPU L1 到主記憶體差 100 倍,主記憶體到 SSD 差 1,000 倍,SSD 到遠端伺服器可以差到 1,000,000 倍。

這就是為什麼快取的每一個層次都值得認真對待:你在哪個層次命中快取,決定了省下多少數量級的等待時間。網頁快取的目標是讓資源在 CDN 邊緣節點就命中,不必跨越到 origin server,差距是 50 ms vs 400 ms。對 LCP 這個以毫秒計算的指標,這個差距非常關鍵。

網頁快取的三個主要層級

在 web 效能的語境下,快取主要分三層,每層的作用位置和控制方式都不同。

網頁資源請求流程圖:快取命中(CDN)vs 快取未命中(Origin),TTFB 差距可達 10 倍
快取命中時 TTFB 約 30ms;快取未命中時需回到 Origin,可達 400ms 以上

瀏覽器快取

瀏覽器快取存在使用者的本機設備上。每次瀏覽器取得一個資源(圖片、CSS、JS、HTML),它會根據回應標頭的指示,決定要不要把這份資源存到磁碟,以及存多久。下次請求同一個 URL 時,瀏覽器先查本機,有的話直接拿,沒有的話才發網路請求。

瀏覽器快取的命中在 Chrome DevTools Network 面板裡可以看到:Size 欄位會顯示「from disk cache」或「from memory cache」,而不是一個下載大小。

這一層完全在用戶端,伺服器端無法強制清除。只有用戶主動清除,或快取過期,才會失效。

CDN 快取

CDN(內容傳遞網路)在全球多個地點放了邊緣伺服器,當使用者請求一個資源,最近的 CDN 節點如果有快取副本,就直接回傳,不必往 origin server 走一趟。

Cloudflare 在全球有 250+ 個邊緣節點,一個台灣用戶請求靜態資源,通常走到台北或東京的節點就拿到了,RTT 在 10–30 ms 範圍內。如果沒有 CDN 快取,同一個請求可能要跨越到美國西岸的 origin server,RTT 輕鬆超過 150 ms。

CDN 快取受 Cache-Control 的 s-maxage 指令控制,也可以透過 CDN 後台手動 purge。要注意 CDN purge 不會清除用戶瀏覽器上的本機快取,這是兩個獨立的層。想深入了解靜態資源(尤其是圖片)如何在 CDN 上最佳化傳輸,可以參考圖片格式與 CDN 傳輸效率的討論。

伺服器快取(應用層)

在 origin server 這一側,應用程式可以把計算好的 HTML 或資料庫查詢結果存在記憶體(例如 Redis 或 Memcached)。下次相同的請求進來,直接從記憶體拿,不必重跑資料庫查詢或模板渲染。

這一層的快取對 TTFB 影響最直接:沒有伺服器快取的動態頁面,TTFB 可能在 500–2000 ms;有 Redis 快取的,可以壓到 20–50 ms。

Cache-Control HTTP 標頭:快取的實際控制機制

Cache-Control 是 HTTP 回應標頭,告訴瀏覽器和中間代理(包括 CDN)怎麼快取這個資源。這是所有 web 快取行為的控制介面,但有幾個指令的行為容易搞混。

Cache-Control HTTP 標頭主要指令對比:max-age、no-cache、no-store、immutable、stale-while-revalidate 行為差異
Cache-Control 各指令的快取行為與 Revalidate 邏輯對比

max-age 和 s-maxage

max-age=86400 告訴瀏覽器這個資源在 86,400 秒(1 天)內都是新鮮的,不需要重新向伺服器確認。1 天內的請求直接從快取拿,不發網路請求。

s-maxage 的邏輯相同,但只對「共用快取」(shared caches,包括 CDN)有效,瀏覽器不理它。當你想讓 CDN 快取某個資源 7 天,但允許瀏覽器每天重新確認,可以這樣設:

Cache-Control: max-age=86400, s-maxage=604800

stale-while-revalidate

stale-while-revalidate 是一個讓快取行為更平滑的機制:在快取過期後的一段時間內,先回傳舊的(stale)內容給使用者,同時在背景向伺服器請求新版本。用戶不需要等待,下一次請求就拿到新的。

Cache-Control: max-age=3600, stale-while-revalidate=86400

這組設定的意思:資源 1 小時內保持新鮮,之後 24 小時內可以繼續用舊的並背景刷新。截至 2026 年,stale-while-revalidate 的瀏覽器支援率已超過 95%。

no-cache 和 no-store 的差別

這是快取裡最容易誤解的兩個指令。

指令 快取行為 重新驗證 適用場景
no-cache 會快取 每次使用前必須向伺服器確認 頻繁更新的頁面(HTML),要保持內容即時性
no-store 完全不存 每次都重新下載 敏感資料(銀行交易記錄、個人健康資訊)
immutable 永遠新鮮 在 max-age 內永不重新驗證 含 hash 的靜態資源(bundle.a1b2c3.js)

no-cache 的名字讓人誤以為它會阻止快取,但實際上它只是要求每次使用快取前要先問伺服器一聲。伺服器回 304 Not Modified 時,瀏覽器繼續用本機的舊版本,根本沒有重新下載任何東西。完整的 MDN Cache-Control 文件列出了所有可用指令的精確行為。

一般靜態資源的建議設定:把 JS/CSS 加上 content hash(bundle.a1b2c3.js),然後設 max-age=31536000, immutable。因為 URL 本身就包含版本資訊,永遠快取是安全的。

快取對 Core Web Vitals 的實際影響

快取不只是「網站顯示舊版本」的問題,它直接影響 Google 用來評估使用者體驗的三個指標。了解 Core Web Vitals 指標的量測方式 有助於把快取優化的數字連結到真實排名信號。

TTFB 與快取命中率的關係

TTFB(Time to First Byte)是瀏覽器送出請求到收到第一個 byte 的時間。它的 "Good" 門檻是 800 ms,但現實中好的網站通常在 200 ms 以下。

CDN 快取命中對 TTFB 的影響很直接:

  • CDN Cache HIT:TTFB 通常在 30–80 ms,取決於邊緣節點距離
  • CDN Cache MISS(往 origin 走):TTFB 很容易到 300–600 ms,動態頁面可能更高

對於靜態資源密集的頁面,CDN 快取命中率每提升 10%,整體頁面的平均 TTFB 就會降一些。實際幅度取決於靜態資源佔整體請求的比例,通常在 50–80% 之間。

快取命中率對 TTFB 的量化影響:CDN HIT 40ms vs MISS 380ms vs 無CDN 460ms
快取策略對 TTFB 的實際影響幅度,CDN 快取命中可讓 TTFB 降至 40ms 以下

LCP 圖片的快取策略

LCP(Largest Contentful Paint)最常見的元素是首圖或 hero image。這張圖片能不能快速載入,決定了 LCP 分數。

LCP 圖片的快取建議:

  • 設定足夠長的 max-age(靜態圖片至少 30 天)加上 s-maxage 讓 CDN 長期快取
  • fetchpriority="high" 確保瀏覽器優先請求 LCP 圖片,讓快取命中更早發生
  • 用 content-hash 命名圖片檔,搭配 immutable 指令,徹底消除不必要的 revalidation round-trip

一次 revalidation round-trip(即使伺服器回 304)在行動裝置上可能是 100–200 ms。把它從 LCP 圖片的請求路徑上移除,LCP 分數通常有明顯改善。LCP 首圖的載入優化有更詳細的 fetchpriority 和圖片快取的配合說明。

Google 在 web.dev HTTP 快取指南裡整理了靜態資源的快取建議,是設定 Cache-Control 的實用參考。

快取命中還是未命中:開發者怎麼看

在 Chrome DevTools 的 Network 面板裡,可以直接觀察每個資源的快取狀態,不需要任何額外工具。

Chrome DevTools Network 面板快取狀態識別:from memory cache、from disk cache、304 Not Modified
DevTools Network 面板中不同快取狀態的顯示方式與含義

打開 F12,切到 Network 面板,重新整理頁面。Size 欄位的值:

  • from memory cache:資源從記憶體快取取得,這次瀏覽期間已經下載過,最快
  • from disk cache:從本機磁碟取得,之前的瀏覽 session 留下的快取
  • 具體數字(如 48.2 kB):這次實際下載了,沒有快取命中

Status 欄位看到 304 Not Modified 是另一種情況:資源有快取,但設了 no-cache,瀏覽器去伺服器確認,伺服器說「沒變,繼續用你的快取」。這比重新下載快,但還是多了一個 round-trip。

對效能工程師來說,一個健康的頁面在第二次造訪時,Network 面板裡靜態資源應該絕大多數都是 from disk cache,只有 HTML 文件本身可能是 304 或直接重新取得。如果 JS 或圖片每次都重新下載,就要去看 Cache-Control 標頭的設定有沒有問題。

什麼時候該清快取:三種情境的決策邏輯

清快取是個經常被過度建議的操作,搞清楚要清哪一層、在什麼情況下清,才不會白做工。

  • 情境 1:網站更新後舊版本還在。先確認是哪一層的問題。CDN 快取可以從 Cloudflare 後台 purge,也可以等 TTL 自然過期。瀏覽器快取只能用 cache-busting(改 URL hash)強迫更新,或等 max-age 到期。如果你的 HTML 設的是 no-cache,理論上 Google 每次抓都會拿到最新版本,問題可能出在 CDN 那一層。
  • 情境 2:開發時看不到最新改動。Chrome 的 Hard Reload(Shift + F5,或 DevTools 開著時按 F5)會跳過快取,送一個帶 Cache-Control: no-cache 的請求。或者在 DevTools Network 面板勾選「Disable cache」,整個 session 都不用快取。
  • 情境 3:使用者端的問題診斷。引導用戶清除瀏覽器快取前,先確認問題是不是真的出在快取。用無痕模式(Incognito)開網站,如果問題消失了,確實是本機快取的問題;如果還在,問題在伺服器或 CDN,清瀏覽器快取沒用。

Phil Karlton 說過一句工程圈很有名的話:「電腦科學裡只有兩件難事,快取失效和命名。」快取失效之所以難,是因為你必須在「資料保持新鮮」和「減少網路請求」之間找到平衡,而這個平衡點因資源類型、更新頻率、用戶群分佈而異。沒有一個設定對所有情況都最優。

常見問題 FAQ

快取和 Cookie 有什麼不同?

快取存的是網站資源的副本(圖片、JS、CSS、HTML),目的是加快載入速度。Cookie 存的是用戶相關的狀態資訊(登入 token、偏好設定、購物車),用於識別身份和傳遞資料給伺服器。兩者都在瀏覽器端存資料,但用途完全不同。清除瀏覽器快取不會清 Cookie,反之亦然。

清除瀏覽器快取會刪除密碼或登入狀態嗎?

不會。密碼存在密碼管理器裡,登入狀態存在 Cookie 或 Session storage 裡。清除快取只會刪掉網站資源的本機副本。但如果你同時勾選「清除 Cookie」,那才會讓你登出所有網站。許多人混淆這兩件事,結果清快取後發現自己被登出,其實是連 Cookie 一起清了。

快取檔案累積多了會不會影響電腦速度?

正常情況下影響很小。瀏覽器對快取大小有上限(Chrome 預設約 80% 可用磁碟空間的某個比例,通常不超過幾 GB),到上限後會自動淘汰最舊的項目。手機上如果儲存空間本來就快滿,快取佔用的幾百 MB 才會有感覺。一般情況下定期清快取不會讓電腦明顯變快,反而第一次造訪網站時會變慢,因為要重新下載所有資源。

網站更新後,Google 怎麼知道要抓新版本?

Google 的爬蟲本質上就是一個 HTTP 客戶端,它也遵守 Cache-Control 標頭。如果你的 HTML 設了 no-cache 或較短的 max-age,爬蟲每次來都會重新確認。更積極的做法是在更新後透過 Search Console 請求重新索引,或使用 IndexNow API 主動通知。CDN 層面要先 purge,確保爬蟲不會拿到 CDN 快取的舊版本。

CDN 快取和瀏覽器快取要分開清嗎?

是的,這是兩個獨立的快取層,清一個不會影響另一個。發布網站更新後,正確流程是:先 purge CDN 快取(從 Cloudflare 或你用的 CDN 後台操作),讓新版本從 origin 同步到邊緣節點。瀏覽器快取的部分,如果是靜態資源,用 content-hash URL 的 cache-busting 是最可靠的做法,因為 URL 變了,瀏覽器認為是全新資源,自然會下載新的。

Cache-Control 的 max-age 設多久比較好?

看資源類型。帶 content-hash 的 JS/CSS/圖片(如 app.a1b2c3.js):設 1 年(31,536,000 秒)加 immutable,URL 變了就是新資源,永遠不用擔心快取失效。HTML 文件:設 no-cache 或很短的 max-age(60–300 秒),確保內容即時性。API 回應:依業務邏輯定,幾分鐘到幾小時都合理。字體和第三方靜態資源:1 天到 1 週。沒有放諸四海皆準的設定。

no-cache 和 no-store 一樣嗎?

不一樣,行為差很多。no-cache 允許快取,但每次使用前必須先向伺服器驗證資源是否過期。伺服器回 304 表示沒變,瀏覽器繼續用本機的;回 200 就下載新的。no-store 則是完全禁止儲存,每次都重新下載,沒有任何本機副本。只有真正敏感的資料(例如醫療記錄、金融交易)才需要 no-store。一般頻繁更新的頁面用 no-cache 就夠了,還能享受 304 節省的頻寬。

快取命中率(Cache Hit Rate)多少算合格?

對 CDN 快取來說,靜態資源的命中率低於 80% 就要開始懷疑設定有問題。高流量網站的靜態資源命中率通常在 90–99%。動態頁面因為內容個人化,命中率本來就低,不要和靜態資源混在一起算。可以在 Cloudflare 的 Analytics 或 CDN 後台看到命中率數據。命中率持續低的常見原因:Cache-Control 沒設、URL 帶有隨機查詢參數導致每次被視為不同資源、快取 key 包含了 Cookie 或其他變動因子。

陳柏翰

網站效能工程師

專注前端效能優化超過 8 年,曾協助電商、媒體和 SaaS 平台改善 Core Web Vitals 指標。相信效能優化應該基於數據而非直覺。

50+ 效能實驗
8 年 前端經驗
200+ 優化案例

想看更多?

探索所有效能實驗

查看完整的實驗報告列表,找到你需要的效能優化方案。

所有實驗報告 免費效能診斷