强缓存

强缓存:浏览器自己判断资源是否在有效期内,直接使用本地副本,不发请求。

#tech / dev / frontend #type / concept #status / evergreen #platform / browser #tech / network

[!info] related notes

强缓存

强缓存:浏览器自己判断资源是否在有效期内,直接使用本地副本,不发请求。

核心机制

浏览器检查本地缓存是否”新鲜”(fresh):

  • 新鲜:直接返回本地副本,状态码 200 from cache
  • 不新鲜:进入协商缓存流程

新鲜度计算

浏览器根据 max-ageAge 头部计算剩余新鲜时间:

freshness_lifetime = max_age - age - response_delay
  • max-age:缓存有效时长(秒)
  • age:响应在缓存中已存在的时间(代理/CDN 添加)
  • response_delay:浏览器到上一跳的网络延迟

详见 → Age、Date 与新鲜度计算

控制头

Cache-Control(现代主流)

Cache-Control: max-age=3600          # 3600 秒内直接用
Cache-Control: public                # 允许 CDN/代理缓存
Cache-Control: private               # 只有浏览器能缓存
Cache-Control: immutable             # 有效期内绝不会变

Expires(HTTP/1.0 遗留)

Expires: Wed, 08 Apr 2026 12:00:00 GMT

优先级Cache-Control > Expires > 启发式缓存(当两者都不存在时,浏览器可能用 Last-Modified 猜测新鲜度)

Cache-Control 指令速查

响应指令

指令含义
max-age=<seconds>缓存有效时长(秒)
s-maxage=<seconds>仅共享缓存(CDN/代理)使用的有效时长,浏览器忽略,优先级高于 max-age
public允许任何缓存节点存储
private只允许浏览器私有缓存
immutable有效期内内容不会变化
no-cache可缓存,但用前必须验证(不是不缓存!)
no-store不存储(真正的不缓存)
must-revalidate过期后必须重新验证,不能使用过期副本
proxy-revalidate类似 must-revalidate,但仅对共享缓存生效
stale-while-revalidate过期后先返回旧缓存,同时后台更新
stale-if-error更新失败时允许用过期副本
no-transform代理不得修改响应体(如图片压缩、转码)

请求指令

指令含义
no-cache强制重新验证(浏览器强刷时发送)
max-age=0等价于强刷,要求缓存立即过期
only-if-cached只使用缓存,不发网络请求(离线模式)
no-store请求和响应都不可缓存

[!tip] 浏览器强刷(Ctrl+Shift+R)发送的请求头通常同时包含 Cache-Control: no-cachePragma: no-cache

no-cache vs no-store(最常见误区)

指令行为
no-cache可以缓存,但每次使用前必须去服务器验证
no-store连存都别存,真正的不缓存

记忆口诀:no-cache 是”存可以,直接用不行”;no-store 是”连存都别存”。

stale-while-revalidate 详解

Cache-Control: max-age=60, stale-while-revalidate=300

时间线:

  • 0-60 秒:新鲜,直接用缓存
  • 60-360 秒:已过期,但浏览器仍然返回旧缓存,同时在后台发起验证请求
  • 360 秒后:必须同步验证,不能再用旧缓存

这是很多 CDN 和前端框架(Next.js、Nuxt)使用的模式——用户永远不等网络,代价是最多 5 分钟的旧数据。

stale-if-error 详解

Cache-Control: max-age=3600, stale-if-error=86400
  • 正常情况:3600 秒内直接用缓存
  • 过期后如果验证失败(网络错误、5xx):允许继续使用旧缓存最多 86400 秒(1 天)

适合对可用性要求高、对数据新鲜度容忍度较大的场景。

immutable 深入

Cache-Control: max-age=31536000, immutable

告诉浏览器:这个资源在整个有效期内绝对不会变。浏览器在用户主动刷新(F5)时也可以跳过重新验证。

浏览器支持

  • Firefox:支持
  • Safari:支持
  • Chrome:不支持(截至 2026 年),退化为普通 max-age 行为

典型场景:带内容哈希的静态资源。详见 → 缓存失效与部署策略

典型应用场景

# 带 hash 的静态资源(长期缓存)
Cache-Control: public, max-age=31536000, immutable

# 图片(中期缓存)
Cache-Control: public, max-age=86400

# HTML 主文档(每次验证)
Cache-Control: no-cache

# 用户敏感数据(不缓存)
Cache-Control: no-store, private

性能优势

强缓存是性能最好的方式:

  • 不发请求
  • 零网络延迟
  • 省带宽
创建于 2026/4/7 更新于 2026/5/27