90%的人搞反了:如果你只改一个设置:优先改缓存管理

标题:90%的人搞反了:如果你只改一个设置:优先改缓存管理

90%的人搞反了:如果你只改一个设置:优先改缓存管理

开门见山:如果你只能在网站性能、稳定性或SEO上做一项调整,那就把注意力放在缓存管理(Cache-Control/Expires/TTL)上。大多数人把缓存当成“交给服务器或CDN默认即可”的无脑选项,结果要么频繁被缓存问题折腾,要么浪费带宽和加载时间。下面讲清楚为什么、常见错误、以及怎样一步到位把缓存做对。

为什么缓存管理比你想的还要关键

  • 用户体验:合理缓存能显著降低页面加载时间,尤其是重复访问或跨页面共享静态资源时。
  • 成本与带宽:正确设置缓存可减少源站流量,降低CDN/主机费用。
  • 稳定性与可用性:当源站压力高或短暂不可用时,CDN缓存可以继续对外提供内容。
  • 可控更新:配合资源版本号(fingerprinting),可以在保证长期缓存的同时,随时发布新版本而无需担心旧资源被继续使用。

大多数人常犯的错误(见招拆招)

  • 把 HTML 页面和静态资源同等对待:HTML 通常需要短缓存或必须校验更新;而 js/css/png 等静态文件应该长期缓存并通过文件名版本化管理更新。
  • 依赖 ETag 而不设置合理的 max-age:ETag 会导致每次还是要回源校验,失去了减少往返的优势。
  • 忽视 CDN 的 TTL 与源站 Header 不一致:CDN 可能会覆盖或忽略源站设置,导致缓存策略失效。
  • 不做缓存失效策略(版本号、query string 的使用混乱):没有资产指纹,更新时只能清缓存或冒风险用户看到旧内容。
  • 错误使用 no-cache/no-store:把 no-store 用到所有页面,彻底禁止缓存,进而增加延迟和流量。

如果你只改一个设置,应改什么? 核心答案:为静态资源设置长期缓存(Cache-Control: public, max-age=31536000, immutable)并结合资源指纹化(文件名包含 hash)。同时为 HTML 设置短缓存或 no-cache 以便快速回收更新。把这两条当作一对策略:静态长期缓存 + 文件指纹;动态或频繁更新的内容短缓存/可校验。

推荐的具体策略(可直接应用)

  • 静态资源(js/css/png/jpg/svg/fonts):Cache-Control: public, max-age=31536000, immutable
  • max-age=31536000 等于一年;immutable 告诉浏览器资源不会改变(更安全)。
  • 使用文件名指纹(例如 app.abc123.js),每次构建生成新的 hash。
  • HTML 页面与动态内容:Cache-Control: no-cache, must-revalidate, proxy-revalidate, max-age=0
  • no-cache 允许缓存但每次回源校验,确保页面变化能被及时感知。
  • 对于需要更高性能的页面,可使用短的 max-age(比如 60 秒)并配合 stale-while-revalidate。
  • API 响应:根据数据敏感度选择 private 或 no-store。非敏感但可缓存的响应可使用 Cache-Control: public, max-age=60, s-maxage=60(s-maxage 指 CDN 专用)。
  • 敏感数据(登录、支付页等):Cache-Control: no-store

实操命令与配置示例

  • 用 curl 快速检测:
  • curl -I https://yourdomain.com/static/app.abc123.js
  • 查看响应头中的 Cache-Control、Expires、ETag 是否符合预期。
  • Nginx(静态资源长期缓存):
  • location ~* .(js|css|png|jpg|jpeg|gif|svg|woff2)$ { expires 365d; add_header Cache-Control "public, max-age=31536000, immutable"; }
  • Apache (.htaccess):
  • ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year"
  • Header set Cache-Control "public, max-age=31536000, immutable"
  • Cloudflare(示例 Page Rule):
  • URL pattern: example.com/static/* -> Cache Level: Cache Everything, Edge Cache TTL: a month/1 year(并确保 origin 缓存头被尊重或使用“Origin Cache Control”)。
  • WordPress(W3 Total Cache / WP Super Cache):
  • 开启浏览器缓存(Browser Cache),设置静态资源的浏览器缓存到 31536000 秒;使用版本化插件(比如 WP-Optimize 或使用主题/构建工具自动版本化资源)。

验证与常见排查步骤

  • 浏览器 DevTools -> Network:访问资源看 Size 与 Status,若显示 200 (from disk cache) 或 200 (from memory cache) 表明缓存生效;304 表示回源校验。
  • 检查是否存在过多的 Set-Cookie 或 Vary: * 头部,这会阻止缓存。
  • 确认 CDN 是否覆盖了源站缓存头,必要时在 CDN 配置中选择“尊重源站缓存头”或手动设置 CDN TTL。
  • 推出新版本时,确认构建流程会更新资产 hash;不靠 query string 处理更新(某些 CDN 对 query string 缓存行为不同)。

一步到位的行动清单(3分钟起步)

  1. 对静态资源启用长期缓存头:Cache-Control: public, max-age=31536000, immutable。
  2. 在构建/部署中加入文件指纹(hash)策略,确保每次发布更新都会改变文件名。
  3. 将 HTML/首页设为 no-cache 或短 max-age,并考虑使用 stale-while-revalidate。
  4. 在 CDN/代理上确保 TTL 与源站策略一致,并测试回收(purge)流程。
  5. 用 curl 与浏览器 DevTools 验证所有关键资源的 Cache-Control 是否按预期工作。

结语 把缓存管理当作“只有专家才管的微调”会让你付出显而易见的性能、费用与稳定性代价。把静态资源长期缓存与资源指纹化作为首要设置,HTML 保持短缓存或可校验,这样在最少投入下能获得最大的收益。改对缓存,这一项能带来的回报,通常比改任何单独的性能优化都要明显。