在前端性能优化的广阔领域里,“缓存”永远是投入产出比最高的那张王牌。

很多开发者对缓存的理解还停留在“在 Nginx 里配个 Cache-Control”或是“背诵 304 状态码”的阶段。一旦遇到“发版后用户还是看到旧页面(缓存幽灵)”或者“弱网环境下页面白屏”等线上事故,往往束手无策。

本文将一条线串起现代前端缓存的演进脉络,从最基础的 HTTP 协议,一路讲到当今 PWA 和大厂离线包底层的核心技术。

一、 缓存基石:HTTP 协议的“推拉博弈”

浏览器与服务器的缓存博弈,本质上分为两派:强缓存协商缓存

1. 强缓存:客户端的“独裁”

  • 核心逻辑:只要没过期,连问都不问服务器,直接从本地硬盘/内存读取数据。速度极快(0ms 延迟,0 网络流量)。
  • 控制字段Cache-Control: max-age=31536000(现代标准)或 Expires(HTTP/1.0 历史遗留)。
  • 💡 避坑指南:很多面试题常考 no-cacheno-store 的区别。
    • no-cache 不是不缓存,而是每次使用前必须去服务器验证(强制走协商缓存)。
    • no-store 才是真正的“绝对不缓存”,常用于涉及隐私的敏感数据。

2. 协商缓存:经典的 304 Not Modified

如果强缓存失效,或者设置了 no-cache,浏览器就会带着两套“暗号”去向服务器请示:

  • 精确打击:ETag / If-None-Match
    • 服务器给文件算出一个哈希值(指纹)叫 ETag。下次请求时,客户端带上这个指纹,服务器对比哈希值。没变就返回 304它的优先级最高。
  • 时间刻度:Last-Modified / If-Modified-Since
    • 基于文件的最后修改时间来判断。缺点是只能精确到秒,如果文件在 1 秒内被多次修改,会发生误判。

二、 现代前端工程的标准答案

在 React / Vue 等单页应用(SPA)横行的今天,业界摸索出了一套几乎能解决 90% 日常场景的黄金法则:文件指纹 + HTTP 缓存组合拳

在 Webpack 或 Vite 打包时,我们会这么做:

  1. 入口文件 (index.html):设置为 Cache-Control: no-cache。确保每次用户打开网页,都去服务器拉取最新的骨架。
  2. 静态资源 (app.[hash].js, logo.[hash].png):基于内容生成哈希文件名,并设置 1 年以上的强缓存

奇妙的化学反应:如果代码没改,用户请求 index.html,拿到旧的 DOM,里面的 JS 文件名没变,直接秒读本地强缓存。如果发了新版,index.html 里的 JS 文件名变成了新的 Hash,浏览器发现本地没有,就会去精准下载那几个变动的文件。 这套方案无需写任何业务代码,零维护成本,完美实现了“极速的增量更新”。

三、 打破天花板:Service Worker 的降维打击

HTTP 缓存再好,也有两个致命弱点:

  1. 怕断网:一旦完全没网,连 index.html 都拉不到,直接白屏。
  2. 被动加载:必须用户点进去过,才会产生缓存。

当我们需要真正实现“离线可用(Offline First)”或“弱网秒开”时,Service Worker (SW) 就出场了。 它相当于在浏览器和网络之间安插了一个“独立的反向代理服务器”。不仅能拦截所有请求,还能主动在后台拉取并缓存预期的资源。

四、 Workbox:将高深架构变为傻瓜配置

手写 Service Worker 的 Cache API 极其痛苦,且极易引发“用户永远看不到新代码”的毁灭级 Bug。为此,Google 推出了 Workbox。它是 SW 界的 jQuery,将复杂的缓存路由变成了几行优雅的配置。

理解 Workbox,只需要掌握它的三大核心策略:

  1. Cache First (缓存优先)
    • 有缓存就直接用,死也不找服务器。适合字体文件、带 Hash 值的打包图片。
  2. Network First (网络优先,断网降级)
    • 优先拉取最新数据。但如果用户进入电梯或地铁断网了,自动掏出上一次的缓存顶上,保证页面不崩溃。适合高频更新的 API 列表页。
  3. 🌟 终极王牌:Stale-While-Revalidate (陈旧但后台验证)
    • 这是目前公认用户体验最好的策略。请求发出时,分两步走
    • 第一步:立刻将缓存里的旧数据展现给用户(零延迟,屏幕瞬间有内容)。
    • 第二步:在后台悄悄向服务器请求新数据,拿到后更新到缓存里。用户下次刷新时,看到的就是最新内容。
    • 既保证了如原生 App 般的秒开速度,又兼顾了数据的最终一致性。

总结:你的项目该如何选型?

  • 90% 的中后台系统 / 普通 C 端网页:保持简单。依靠打包工具的 Hash 机制 + Nginx 静态目录的 Cache-Control 已经足够。
  • 强依赖移动端弱网环境 / 追求极致体验的 C 端产品(如在线文档、大型 H5 活动):果断引入 Workbox 搭建 PWA 架构,享受缓存策略带来的降维体验提升。

技术的魅力在于没有绝对的银弹,只有权衡。深刻理解每一个 HTTP Header 和缓存策略背后的代价,才是高级工程师的必修课。

Leave a comment