Skip to content

根据你提供的文章内容,我们可以为浏览器缓存机制中的 四种缓存类型(Memory Cache、Service Worker Cache、HTTP Cache、Push Cache) 以及 HTTP 缓存内部的强缓存与协商缓存决策逻辑 分别绘制清晰的流程图。以下是文字版流程图(可直接用于绘图工具如 draw.io、Mermaid、ProcessOn 等):


🌐 一、浏览器缓存整体命中流程图(按优先级)

开始


是否命中 Memory Cache?
  ├─ 是 ──► 从内存返回(from memory cache) ──► 结束

  ▼ 否
是否命中 Service Worker Cache?
  ├─ 是 ──► 从 Service Worker 返回(from ServiceWorker) ──► 结束

  ▼ 否
是否命中 HTTP Cache(强缓存)?
  ├─ 是 ──► 从 HTTP 缓存返回(200 from disk/memory cache) ──► 结束

  ▼ 否
是否命中 Push Cache(HTTP/2 Server Push)?
  ├─ 是 ──► 从 Push Cache 返回 ──► 结束

  ▼ 否
发起网络请求 → 服务器


结束

说明

  • Push Cache 是最后一道防线(如原文所述)。
  • Service Worker 的 fetch 事件可拦截请求并决定是否使用缓存或走网络。

🔒 二、HTTP 缓存内部决策流程图(强缓存 → 协商缓存)

开始:浏览器发起资源请求


检查 Cache-Control / Expires(强缓存)

  ├─ 若存在且未过期(如 max-age 有效)?
  │     ├─ 是 ──► 直接使用缓存(200,无网络请求) ──► 结束
  │     └─ 否 ──► 进入协商缓存


协商缓存:检查 ETag / Last-Modified

  ├─ 是否有 ETag?
  │     ├─ 是 ──► 发送 If-None-Match 头到服务器
  │     └─ 否 ──► 发送 If-Modified-Since(基于 Last-Modified)


服务器比对资源是否变化

  ├─ 未变化(304 Not Modified)?
  │     ├─ 是 ──► 使用本地 HTTP 缓存 ──► 结束
  │     └─ 否 ──► 返回新资源(200 + 新内容) ──► 更新缓存 ──► 结束

优先级规则

  • Cache-Control > Expires
  • ETag > Last-Modified
  • no-store:跳过所有缓存,强制请求
  • no-cache:跳过强缓存,直接走协商缓存

🧠 三、Cache-Control 决策指南流程图(基于 Chrome 官方建议)

资源是否可复用?
  ├─ 否 ──► Cache-Control: no-store ──► 结束

  ▼ 是
是否每次都需要验证缓存有效性?
  ├─ 是 ──► Cache-Control: no-cache ──► 配置 ETag/Last-Modified ──► 结束

  ▼ 否
是否允许代理服务器缓存?
  ├─ 否 ──► Cache-Control: private, max-age=xxx
  ├─ 是 ──► Cache-Control: public, s-maxage=xxx, max-age=yyy


配置 max-age(客户端有效期)和 s-maxage(代理服务器有效期)


是否需要精准感知内容变更?
  ├─ 是 ──► 启用 ETag(推荐)
  └─ 否 ──► 可仅用 Last-Modified


结束

💾 四、Memory Cache 存储策略(启发式规则)

资源请求到达


资源类型是 Base64 图片?
  ├─ 是 ──► 极大概率存入 Memory Cache

  ▼ 否
资源体积是否较小(如 < 100KB)?
  ├─ 是 ──► 可能存入 Memory Cache(JS/CSS 优先)

  ▼ 否
存入 Disk Cache(或不缓存)


结束

⚠️ 注意:Memory Cache 生命周期 = Tab 进程生命周期,关闭即清空。


🛰️ 五、Push Cache 关键特性总结(非流程,但可作决策参考)

  • 触发条件:服务器通过 HTTP/2 Server Push 主动推送资源。
  • 命中时机:仅当其他所有缓存都未命中时才检查 Push Cache。
  • 生命周期:绑定 HTTP/2 连接,连接关闭即失效。
  • 共享性:同一连接下的多个页面/请求可共享 Push Cache。
  • 浏览器兼容性差(尤其 Safari/Edge),慎用(参考 Jake Archibald 文章)。
  • 替代方案:优先使用 <link rel="preload">,更可靠、易调试。

✅ 建议:实际开发缓存策略推荐

  1. 静态资源(JS/CSS/图片)

    • 设置 Cache-Control: public, max-age=31536000(1年)
    • 文件名加 hash(如 app.a1b2c3.js),实现“永久缓存 + 更新即换名”
  2. HTML 页面

    • 设置 Cache-Control: no-cache,确保每次协商最新内容
  3. API 数据(JSON)

    • 通常设 Cache-Control: no-store 或短 max-age + private
    • 敏感数据避免缓存
  4. 避免使用 HTTP/2 Push(除非你深度测试过各浏览器行为)

    • 改用 <link rel="preload"> 更安全

如需将上述内容转为 Mermaid 代码draw.io XML,我也可以为你生成。是否需要?