Skip to content
大纲

缓存控制

在实际应用中存在大量重复的资源获取,在获取资源时会优先进行强缓存匹配,若命中失败,则发送 HTTP 请求由服务端判断是否命中协商缓存;借助合理的缓存控制可以大幅提高资源获取效率。

缓存位置

客户端查询缓存时依据以下缓存位置的优先级进行

  1. Service Worker:用于 PWA,缓存可自由控制且持续
  2. Memory Cache:效率高,容量小,时效短(进程关闭时释放),常见于页面刷新和预加载(preloader)
  3. Disk Cache:效率低,容量大,时效长,客户端最常见的缓存方式
  4. Push Cache:HTTP2,只在会话中存在,且缓存只能被使用依次

缓存策略

通常客户端的缓存策略分为两种

  • 强缓存:不会发送请求,直接从 Memory Cache 和 Disk Cache 中获取
  • 协商缓存:强缓存未命中时发起请求,由服务端判断是否命中缓存

强缓存根据 Cache-ControlExpires 字段判断是否命中,命中时返回 200from memory/disk cache

  • Expires: [具体时间]: HTTP1.0,存在服务端与客户端时间不一的问题
  • Cache-Control: [指令]: HTTP1.1,优先级高于 Expires,多个指令使用逗号分隔
    • max-age=xxx: 单位秒,表示最大缓存时间
    • s-maxage=xxx: 覆盖 max-age,只在代理服务器中生效
    • no-store: 不缓存
    • no-cache: 资源被缓存但立即失效,下次请求时走协商缓存
    • public: 表示响应可被客户端和代理服务器缓存
    • private: 表示响应只可被客户端缓存
    • max-stale=xxx: 可容忍最大过期时间,指定时间内即使过期也使用当前缓存
    • min-fresh=xxx: 可容忍最小新鲜度,指定时间内希望获取最新响应

协商缓存根据 Last-ModifiedEtag 字段判断是否使用缓存,命中时返回 304Not Modified

  • Last-Modified: [具体时间]: HTTP1.1,根据资源修改时间判断是否使用缓存(存在精度、负载均衡服务器中时间不一致问题)
    • 客户端首次请求时,服务端在响应头添加 Last-Modified 字段
    • 客户端再次请求时,客户端在请求头添加 If-Modified-Since 字段(值同上次返回的 Last-Modified)
    • 服务端接收请求后,根据 If-Modified-Since 与对应资源最后修改时间进行对比判断是否使用缓存
  • ETag: [资源标识]: HTTP1.1,优先级更高,根据资源内容生成的唯一标识判断是否使用缓存(会有额外开销)
    • 服务端根据资源内容生成对应的唯一标识
    • 客户端首次请求时,服务端在响应头添加 ETag 字段
    • 客户端再次请求时,客户端在请求头添加 If-None-Match 字段(值同上次返回的 ETag)
    • 服务端接收请求后,根据 If-None-Match 与对应资源的 ETag 进行比对判断是否使用缓存