一文搞懂HTTP缓存,面试再也不怕了

542 阅读4分钟

前言

当我们访问浏览器网址的时候,浏览器会加载各种资源(如HTML、CSS、JS、图片等)。如果网络环境不是很好,首次加载该网址的响应是相对较慢的,后续的访问却会快很多。这就是浏览器缓存带来的性能优化了。那么我们就去了解一下浏览器缓存(HTTP缓存)

一.缓存目的

a)减少网络请求次数,降低服务器压力,提高网页加载速度
b)提升网页加载速度,提高用户体验

二.缓存流程

客户端首次请求:: 向服务器发起HTTP请求
服务端响应:: 服务器收到请求后,返回资源数据,并根据缓存策略返回响应标头。通过Cache-Control指定缓存, Expiresmax-ageage控制缓存时间,ETag控制版本等
客户端再次请求相同资源:: 检测是否有强缓存,有效直接使用缓存的副本
a) 强缓存失效则通过协商缓存:: 使用ETagIf-None-MatchLast-ModifiedIf-Modified-Since判断是否有效
a1) 协商缓存-有效:: 服务器返回304 复用缓存副本
a2) 协商缓存-无效:: 服务器返回数据资源,缓存该资源的新副本

为了更直白详细的展示,我们给缓存的流程画一个流程图

缓存流程.png

三.缓存类型

如上缓存流程图所示, 缓存分为 强缓存协商缓存

强缓存(Strong Cache)

强缓存不会向服务器发送请求,直接从缓存中读取资源 主要通过设置HTTP响应头中的ExpiresCache-Control来控制
image.png

Cache-Control (HTTP/1.1 优先级高于Expires)

常用指令说明参数值
max-age=<seconds>缓存有效期(单位:秒)必填,eg: max-age=3600 表示缓存有效期为1小时
no-cache不使用强缓存,但响应头中会包含缓存标识,用于协商缓存 同Pragma(HTTP/1.0): no-cache-
no-store完全禁止缓存(强制进入重新请求阶段)-
public浏览器和代理服务器都可以缓存-
private仅允许浏览器缓存(默认)-
immutable永远不会改变可以加上该参数,谨慎使用-

Expires (HTTP/1.0遗留字段)

Expires: 指定资源过期时间 eg: Expires: Wed, 15 Apr 2026 03:19:25 GMT

问题: 判断缓存是否过期依赖本地时间,意味着可以通过修改客户端本地时间让缓存延期

协商缓存(Negotiate Cache)

强缓存失效时,浏览器携带验证信息向服务器确认资源是否变化

image.png

ETag(优先级高于Modified)/If-None-Match

ETag: 服务器返回资源的唯一标识符(哈希值)

参数: W/hash ETag: W/"6800ea08-18e8b" 或 hash ETag: "6800ea08-18e8b"

  • W/标识: 对大小写敏感,表示使用弱验证器
If-None-Match: 请求标头版本号

浏览器下次请求时携带该标识(浏览器在请求资源时附加的上次请求资源时服务器返回的ETag) 用于和服务器的ETag比较

Last-Modified/If-Modified-Since

Last-Modified 响应标头

服务器返回资源时附加最后修改时间 eg: Last-Modified: Wed, 09 Apr 2025 02:50:59 GMT

If-Modified-Since 请求标头

浏览器在请求资源时附加上次请求资源时服务器返回的最后修改时间 eg: If-Modified-Since: Wed, 09 Apr 2025 02:50:59 GMT

四.缓存存储位置分类

1.浏览器端存储

内存缓存(Memory Cache):临时存储高频资源,随标签页关闭释放

  • 优先存储 高频的小型资源(eg: JS/CSS), 速度快,但容量有限

磁盘缓存(Disk Cache)‌:持久化存储低频资源,重启后仍有效‌

  • 存储低频或较大资源(如图片),容量更大且持久化‌

Service Worker缓存‌:通过脚本独立管理缓存,需HTTPS协议支持

2.网络层

代理服务器/CDN缓存‌:由Cache-Control: public控制,允许中间节点缓存资源
HTTP/2推送缓存(Push Cache)‌:会话级临时存储,有效期约5min

缓存优先级: Service Worker 缓存 > 内存缓存 > 磁盘缓存 > HTTP/2 推送缓存(Push Cache)

五.缓存的分类

HTTP Caching 标准中,有两种不同类型的缓存:私有缓存共享缓存
私有缓存
私有缓存是绑定到特定客户端的缓存——通常是浏览器缓存。由于存储的响应不与其他客户端共享,因此私有缓存可以存储该用户的个性化响应

共享缓存
共享缓存位于客户端和服务器之间,可以存储能在用户之间共享的响应。共享缓存可以进一步细分为代理缓存和托管缓存 有兴趣的可以更多参考