浏览器缓存通过 强缓存 和 协商缓存 机制优化性能: 浏览器缓存是指将请求响应的数据存放在本地,通过缓存机制来提升效率优化性能。
- 强缓存 由无需网络请求,由响应头字段
Cache-Control相对时间有效期(优先级高更加精细,如max-age=3600) 和Expires绝对时间有效期来控制,浏览器访问服务器资源时,会先让请求时间和相对时间有效期进行对比,如果没过期,直接返回本地缓存(状态码200 from cache),适用于静态资源(如图片/CSS/JS); - 当强缓存失效时,触发 协商缓存:需要网络验证,有两种方式来实现:
2.1. 通过请求头字段 If-Modified-Since字段(对应响应头 Last-Modified字段)来实现的。当资源过期了,发现响应头里面有last-modified最新修改时间,再发请求的时候就会带上if 和 last发过去,当服务器发现有if-modifed-since字段传过来就会校验传过来的最新修改时间,如果传过来的小,就说明资源修改了,就返回最新资源,如果传过来的大,说明资源没被修改,就返回304复用本地缓存。
2.2 通过请求头字段If-None-Match字段(对应响应头 ETag字段) 来实现的。当资源过期了,返现响应头里面有etag字段也就是唯一标识响应资源,再发请求时会将if和etag发过去,当服务器发现有if字段传过来就会判断etag是否发生变化,若资源未修改则返回 304 Not Modified(复用本地缓存),否则返回 200 和新数据;
然后就是etag唯一标识资源的优先级要比last-modified最新修改时间的优先级要高,优化了last-mofidied的一些缺陷:1.没有修改文件内容的情况下也就是说etag没变的情况下,最后的修改时间last-modified也可能改变,就会进行重新请求响应,浪费资源。2.然后就是if-modified-since能查到的粒度是秒级的,而有些文件的修改可能是秒级以内的,这种modified就发现不了服务端资源的修改,而etag唯一标识响应资源就能发现,一秒内能刷新多次。3最后就是服务器并不能精确获取文件的最后修改时间而能精确获取etag的变化。
- 实际开发中,静态资源建议设置长期强缓存(文件名哈希化),HTML 文件禁用缓存(
Cache-Control: no-cache),敏感数据用no-store彻底禁用; - 性能与安全平衡:ETag 比 Last-Modified 更精准(内容哈希 vs 时间戳),但需注意集群服务器的哈希一致性。
一、缓存机制全景图(必考流程图)
[浏览器请求]
│
▼
┌─ 强缓存是否有效?─┐
│(检查Cache-Control/Expires)│
└───────────────┘
│
有效 ▼ 无效 ▼
[直接200(from cache)] → [发起请求到服务器]
│
▼
┌─ 协商缓存是否有效?─┐
│(检查ETag/Last-Modified)│
└───────────────┘
│
有效 ▼ 无效 ▼
[304 Not Modified] [200 OK + 新数据]
二、核心缓存策略(3层递进)
1. 强缓存(无需网络请求)
- 响应头控制:
Cache-Control: max-age=3600 // 相对时间(优先级高) Expires: Wed, 21 Oct 2024 07:28:00 GMT // 绝对时间(兼容旧系统) - 典型场景:
- 静态资源(图片/CSS/JS)配置长期缓存(如
max-age=31536000)
- 静态资源(图片/CSS/JS)配置长期缓存(如
2. 协商缓存(需网络验证)
- 校验头组合:
# 第一次响应 Last-Modified: Fri, 12 Jul 2024 10:30:00 GMT ETag: "abc123" # 后续请求 If-Modified-Since: Fri, 12 Jul 2024 10:30:00 GMT If-None-Match: "abc123" - 工作逻辑:
- 服务器对比时间戳(Last-Modified)或内容哈希(ETag)
- 未修改 → 返回304(省流量)
- 已修改 → 返回200 + 新数据
3. 缓存禁用策略
Cache-Control: no-store // 彻底禁用缓存(敏感数据)
Cache-Control: no-cache // 每次必须验证(类似协商缓存)
三、实战配置指南(前端必会)
1. 静态资源长期缓存
# Nginx配置示例
location /static {
add_header Cache-Control "public, max-age=31536000, immutable";
}
- 最佳实践:文件名带hash(如
app.a1b2c3.js),内容变化自动更新URL
2. HTML文件禁用强缓存
<!-- 防止页面更新不及时 -->
<meta http-equiv="Cache-Control" content="no-cache">
3. API数据缓存策略
# 适合频繁读取的配置
Cache-Control: private, max-age=60 // 客户端缓存1分钟
四、高频考点解析
1. 缓存优先级
强缓存 > 协商缓存 > 实际请求
(先检查本地是否可用,再检查是否过期)
2. ETag vs Last-Modified
| ETag | Last-Modified | |
|---|---|---|
| 精度 | 内容哈希(精确到字节变化) | 时间戳(秒级精度) |
| 典型场景 | 频繁编辑的文件(如wiki页面) | 低频修改的资源(如新闻稿) |
3. 状态码304的特殊性
- 不返回body数据(节省带宽)
- 触发浏览器更新本地缓存过期时间
五、记忆口诀
"强缓存优先查,过期转协商,
ETag精度高,304省流量,
静态资源配哈希,敏感数据no-store"
掌握这些要点,面试遇到缓存问题就能对答如流! 🚀