快速上手 HTTP Cache
2025-01-13
开始系统研究 HTTP Cache,是因为我在开发 裁员追踪器 | Layoffs Tracker🔗 时遇到一个问题:
API 返回的数据是静态的,长时间不更新。如果每次请求都需要访问服务器,不仅效率低下,还会对服务器造成不必要的压力。
所以考虑加一层 Cache。
最简单的实现方式,就是 HTTP Cache。
本以为加几个 HTTP Header 就可以搞定。研究一番后发现,这一块的内容远比想象中丰富。
所以写一篇文章,体系化梳理 HTTP Cache。
重点将放在:产生背景,解决手段,最佳实践。
1. 背景
Cache(缓存)在整个计算机系统里应用广泛。
从最底层的 CPU Cache,到 DNS 解析,CDN,再到耳熟能详的 Redis,本质都是通过缓存提高效率,以空间换时间。
HTTP Cache 同样如此。
它能帮助提高网页的加载速度,优化用户体验,而且可以有效地减轻服务器负载。
举个例子。
一个静态文件,长期不被修改,那么每次刷新都再次请求是不必要的。速度慢,网络开销大,如果文件尺寸较大,还会给服务器带来更多压力。
HTTP Cache 很好地解决了这个问题。将第一次访问的内容缓存在本地,后续获取资源时便可避开网络请求,直接从本地获取。
2. 解决方案
HTTP Cache 主要有两种:
- 强制缓存,客户端直接使用本地缓存
- 协商缓存,客户端向服务器发送请求,由服务器决定是否使用缓存
2.1 强制缓存
强制缓存的关键头部有两个:
-
Expires(不推荐),指定过期的时间点,是一个绝对时间,例如:Expires: Wed, 15 Jan 2025 20:00:00 GMT -
Cache-Control(推荐),使用相对时间,控制手段更丰富。常用指令有:
public: 表示资源可以被随意缓存(共享),例如代理服务器private: 表示资源只允许用户终端缓存(私有),代理服务器不可以缓存no-store: 表示完全不允许缓存no-cache: 可以缓存,但使用前要向服务器验证是否过期must-revalidate: 缓存不过期的话可以继续使用,否则就要向服务器重新请求max-age=3600: 表示资源有效期为 3600 秒s-maxage=3600:覆盖max-age和Expires,但仅用于共享缓存,私有缓存会忽略
我在 裁员追踪器 | Layoffs Tracker🔗 用到的配置如下:缓存时间为 60 秒,而且可以被共享。

Cache-Control 是一个通用字段,服务端和客户端都可以使用。
服务端用它实现在客户端上的缓存策略,反过来,客户端可以重新设置,决定如何使用当前缓存。
例如,浏览器“刷新”按钮,会在请求里会设置 Cache-Control: max-age=0,绕过本地缓存,从服务器获取最新内容。
2.2 协商缓存
相比强制缓存这种单边决策,协商缓存更加复杂:需要客户端和服务端的双向配合。
关键头部有两部分,请求头和响应头。
- 请求头:
If-Modified-Since: 上次修改时间,用于配合Last-ModifiedIf-None-Match: 本地的缓存版本标识(ETag)
- 响应头:
Last-Modified,最后一次修改时间,用于比较资源是否发生修改,精度不如ETagETag,资源的唯一标识,如果原始资源变更,ETag必须重新生成。比较ETag可以更加高效、准确地判断变化的发生
具体工作流程如下:
- 客户端在第一次请求时,会收到
Last-Modified或ETag字段 - 客户端再次请求时,附带
If-Modified-Since或If-None-Match字段 - 服务端根据请求字段,判断缓存是否有效:
- 有效,返回
304 Not Modified,客户端直接使用缓存 - 无效,返回新的资源和状态码
200 OK,当然Last-Modified或ETag同样会返回
- 有效,返回
例如,访问某个 .js 资源:


2.3 优先级
强制缓存和协商缓存可以同时存在。
同时存在时,会优先判断强制缓存是否有效,无效则进一步使用协商缓存。
3. 最佳实践
不同场景适合不同的缓存策略。
对于静态文件,如 CSS、JS 和图像等,通过设置较长的缓存时间,并将版本信息填充到文件名里,避免因缓存时间过久导致未能及时获取最新内容。
例如:
Cache-Control: max-age=31536000- 文件名示例:
style.v2.css、app.123abc.js
对于动态资源,因为变动频率高,协商缓存更合适:
ETag和Last-Modified提供内容变更验证机制- 响应头设置
Cache-Control: no-cache
像那些涉及登陆等隐私相关的,建议禁止缓存:
- 响应头设置
Cache-Control: no-store, private
4. 总结
在优化性能方面,缓存是个简单,但是强大的工具。
以空间换时间,在准确性和效率中找到一种平衡。
组合使用 HTTP Cache,优化加载和网络访问,基本算是前端开发者的必修课。
毕竟,在复杂多变的网络环境中,缓存多少提供了一些确定性。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2025/http-cache/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2025-12-16T08:10:54+08:00