做站点运营,缓存是個两面派。用得好,静態资源直接從訪客浏览器或 CDN 返回,服務器压力小、首屏快;用得不好,运营和編輯就會陷入一種困惑:後台明明改了,前台還是老样子,只能靠“强制刷新”安慰自己——而真實訪客不會替你按 Ctrl+F5。
先分清两類资源
排查缓存問题之前,先把站内资源分成两類,它們的策略完全不同。
- 带指纹的静態资源:CSS、JS、图片、字体,文件名里带一串哈希或版本号,比如 app.3f9a2c.css。這類文件内容變了文件名就變,可以放心長缓存。
- HTML 文档和接口响應:URL 固定,内容却经常變,缓存時間要短,或者干脆走协商缓存。
很多“改了不生效”的锅,其實是 HTML 被長缓存,而不是 CDN 出問题。先看首頁 HTML 的响應头,再往下查。
看响應头,而不是猜
用浏览器開發者工具的 Network 面板或命令行工具查看响應头,重点看這几項:
- Cache-Control:max-age 是浏览器缓存秒數;s-maxage 针對 CDN 等共享缓存;public / private 决定能不能被中間节点缓存;no-store 表示完全不缓存。
- ETag / Last-Modified:给 HTML 用的协商缓存字段。訪客再次訪問时會带條件請求,内容没變就返回 304,省流量又不至于看到舊内容。
- Expires:老字段,和 Cache-Control 冲突时以後者為准,建议只留一個。
- Vary:涉及压缩、語言、设备适配时,寫错會導致缓存串味,A 用戶的頁面被發给 B 用戶。
常见的建议寫法是:静態资源 max-age 设一年並配合 immutable;HTML 设几分钟到一小时的 max-age,同时保留 ETag。注意不要给 HTML 配 immutable,那等于告诉浏览器“永遠別問服務器”。
CDN 這一层要單獨看
即使源站响應头寫對了,CDN 也可能按自己的規則缓存。需要確認几件事:
- 缓存键包含哪些内容:只看 URL,還是把查询參數也算進去?营销參數、跟踪參數是否被忽略?
- 哪些路径會被缓存:通常只缓存静態资源目錄,不要整站通吃,尤其別缓存後台和登入態頁面。
- 回源規則與刷新方式:發布後是等自然過期,還是主動刷新指定目錄。
如果站内有登入態、地域差异或灰度分流,務必確認共享缓存不會把已登入頁面發给未登入訪客,這類問题排查起来最費時間。
更新流程里加一道检查
缓存問题的根源往往不在配置,而在發布流程。把下面几步固定下来,能省掉大部分重复沟通:
- 改 CSS / JS 时,同步更新文件名或版本參數,而不是靠刷新缓存解决。
- 發布後打開無痕窗口訪問一次首頁和一個栏目頁,確認内容已更新;再用工具請求一次,確認响應头符合预期。
- 變更模板或全站公共组件时,提前安排一次缓存刷新,並通知相關同事,避免他們反复提交“頁面没更新”的問题。
- 把缓存相關的改動记錄在發布單上,出問题时能快速回滚。
一份简短的缓存自查清單
- 首頁和栏目頁 HTML 的 max-age 是否過長?
- 静態资源是否都带指纹,是否存在長期不變的文件名?
- 是否存在既设 no-store 又想靠 CDN 加速的矛盾配置?
- CDN 是否缓存了带登入態或個性化内容的响應?
- 發布流程里是否包含一次實际訪問驗證?
缓存配置不需要一次做到完美,先把“改了看不到”和“每次都回源”這两類高频問题理清,再根據訪問日誌逐步調整過期時間。站点运营的很多细节都是這样:不追求一步到位,但每次動完,都清楚自己改了什么。