HTTP缓存实战排查清单

为什么线上总是“明明发版了却没生效”

前端资源更新后,用户仍然看到旧页面,通常不是发布失败,而是缓存策略没有设计好。HTTP 缓存本质上是一个性能与一致性的平衡问题:缓存命中越高,性能越好;资源更新越快,缓存越难长期命中。

排查这类问题不要先改代码,先看三个事实:

  1. 浏览器到底请求了什么 URL。
  2. 服务器返回了什么缓存头。
  3. CDN 是否改写了源站响应。

核心机制:强缓存与协商缓存

强缓存命中时,浏览器不会向服务器发请求,常见头:

  • Cache-Control: max-age=31536000, immutable
  • Expires: ...

协商缓存会发请求,但可返回 304,常见头:

  • ETag + If-None-Match
  • Last-Modified + If-Modified-Since

实践里优先使用 Cache-ControlETagLast-Modified 受文件时间粒度影响,频繁发布时容易误判。

可直接套用的资源分层策略

HTML

  • 建议:Cache-Control: no-cache
  • 原因:HTML 是入口,必须尽快拿到最新版。

JS/CSS/字体等静态资源

  • 文件名带内容哈希,如 app.a1b2c3.js
  • 响应头:Cache-Control: public, max-age=31536000, immutable
  • 原因:一旦文件名变更,旧缓存自然失效。

API 响应

  • 登录态、用户私有数据:Cache-Control: no-store
  • 公共配置、低频变更数据:短 max-age + 协商缓存

5步排查流程(按顺序)

第一步:在浏览器 Network 看“真实请求”

  • 是否命中 from memory cache / from disk cache
  • 状态码是否 304
  • 是否有 Service Worker 接管

第二步:确认 URL 是否可区分版本

如果 URL 不变,且又用了长缓存,用户拿旧文件是预期行为。

第三步:核对响应头

重点核对:

  • Cache-Control
  • ETag
  • Vary
  • Age(经 CDN 时)

第四步:检查 CDN 行为

常见问题:

  • CDN 默认缓存了 HTML
  • 回源时剥离了 ETag
  • 忽略查询参数导致多版本资源被当成同一个对象

第五步:回归验证

至少验证 3 类场景:

  • 首次访问
  • 普通刷新
  • 强制刷新

常见误区

  • 误区 1:只改 Expires 不改 Cache-Control
  • 误区 2:静态资源不用哈希,仅靠“清缓存通知用户”。
  • 误区 3:把所有接口都设成 no-store,导致性能明显下降。
  • 误区 4:忽略移动端 WebView 的缓存行为差异。

一份可执行清单

  • HTML 入口禁止强缓存。
  • 静态资源强缓存 + 文件名哈希。
  • API 按数据敏感度分层缓存。
  • 建立发布后缓存巡检:抽查首页 + 2 个核心业务页。
  • 线上故障 SOP:先取响应头证据,再改配置。

总结

缓存问题本质上是“版本控制问题”。只要入口及时更新、静态资源可版本化、CDN 策略与源站一致,绝大多数“发布不生效”都可以被流程化解决。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""