跳到主要内容
Vabora 开发极客
首页 归档 分类 标签 案例 服务 关于 聊聊需求

缓存不是"加一层":静态站点该缓存什么、缓存多久

缓存做错比不做更糟:改完内容前台不变、登录后被缓存串号、CDN 里躺着半年前的页面。这篇讲清内容站的三层缓存策略与失效方式。

缓存不是"加一层":静态站点该缓存什么、缓存多久 封面

#背景

"加个缓存"是性能优化里最容易被随口说出、也最容易埋雷的建议。内容站尤其明显:

  • 缓存 HTML → 后台改完文章,前台还是旧的,客户以为你没保存;
  • 缓存带会话的响应 → 换个浏览器就是别人的登录态(严重事故);
  • 静态资源没指纹却缓存一年 → 改了 CSS 用户永远看不到新版。

所以问题不是"要不要缓存",而是哪一层、缓存多久、怎么失效。

#做法:三层分开看

#1. 页面 HTML:不缓存,或极短

前台是服务端渲染,一次请求的主要成本是模板渲染 + 若干次查询(本站在毫秒级)。这种量级下缓存 HTML 的收益远小于它带来的"内容不更新"困惑。

结论:HTML 设 no-cache 或 max-age=60,靠单页查询优化解决性能,而不是靠缓存糊住。

text
Cache-Control: no-cache           # 允许浏览器存,但每次校验

#2. 静态资源:内容指纹 + 一年

CSS/JS 用带内容指纹的文件名(site.a1b2c3.css),于是可以放心长缓存:

text
Cache-Control: public, max-age=31536000, immutable

配合 nginx:

nginx
location ~* \.(css|js|woff2|png|jpg|webp|svg)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
    access_log off;
}

注意:图片要分类。素材库里用户上传的图片路径不变(覆盖上传会变内容),所以图片缓存设 30 天而不是一年,避免"换了图还是旧的"。

#3. 数据层:分内容定 TTL

站内的小块数据(标签云、站点统计、llms.txt)适合进程内文件缓存,但要按变化频率给不同 TTL:

数据TTL理由
标签/分类列表10 分钟变化少,出现位置多
首页统计数字5 分钟每次访问都算成本高
llms.txt / sitemap1 分钟要让新文章尽快被抓
访问统计写入不缓存写操作必须落库

并且所有写操作(保存文章、改设置)都要主动清掉相关缓存——TTL 是兜底,不是主要失效手段。

#排查:改了内容前台没变

按这个顺序查,基本一次到底:

  1. 先看 HTML:curl -sI https://站点/posts/xxx | grep -i cache,如果 no-cache 就不是 HTML 缓存的问题;
  2. 再看应用缓存:php vabora cache:clear 后刷新,变了就是应用层 TTL 太长;
  3. 再看 CDN:CDN 的缓存策略常和源站不一致,且要单独刷新;
  4. 最后看浏览器:Ctrl+Shift+R 强制刷新,或换隐身窗口排除本地。

第 3 步是最容易被忽略的:源站明明对,用户在别的城市看到旧页面,问题在 CDN 边缘节点。

#取舍

  • 不上页面级全站缓存:省下的那点 CPU 换来"内容一致性的复杂度",对流量不大的站点是亏的。真到需要时,应该先做查询与模板层优化。
  • 不做 stale-while-revalidate 的复杂组合:语义好,但排障时"为什么我看到的和别人不一样"会变得难以解释;先保证确定性。
  • 运营内容与代码分开失效:改样式只让 CSS 指纹变,不需要刷 CDN 的 HTML;改内容只影响 HTML,不动资源缓存。
最后更新: 本文采用 CC BY-NC-SA 4.0 许可,转载请注明出处与作者。
related

相关文章

评论

还没有评论,来说点什么吧。

发表评论

评论需站长审核后展示 · 最多 1000 字