浏览器的缓存机制主要分为强缓存和协商缓存,它们都是为了提高网页加载速度、减少服务器压力而设计的。以下是它们的详细介绍:
一、强缓存(Strong Cache)
强缓存是指浏览器在请求资源时,先检查本地缓存,如果缓存未过期,则直接使用缓存资源,而不会向服务器发送请求。
1. 实现方式
强缓存通过以下两种 HTTP 响应头实现:
-
Expires:- 是一个绝对时间,表示资源的过期时间。
- 例如:
Expires: Wed, 21 Oct 2023 07:28:00 GMT。 - 缺点:依赖客户端时间,如果客户端时间与服务器时间不一致,可能导致缓存失效或错误。
-
Cache-Control:- 是一个相对时间,优先级高于
Expires。 - 常用指令:
max-age=<seconds>:资源的最大缓存时间(单位:秒)。no-cache:不使用强缓存,直接进入协商缓存。no-store:禁止缓存,每次请求都从服务器获取资源。public:资源可以被所有用户缓存(包括代理服务器)。private:资源只能被客户端缓存。
- 例如:
Cache-Control: max-age=3600,表示资源可以缓存 1 小时。
- 是一个相对时间,优先级高于
2. 强缓存流程
- 浏览器请求资源时,先检查本地缓存。
- 如果缓存未过期(根据
Expires或Cache-Control判断),则直接使用缓存资源。 - 如果缓存已过期,则进入协商缓存流程。
3. 优点
- 减少服务器请求,提升加载速度。
- 适用于静态资源(如图片、CSS、JS 文件)。
二、协商缓存(Conditional Cache)
协商缓存是指浏览器在强缓存失效后,向服务器发送请求,服务器通过校验资源的标识(如最后修改时间或唯一标识)来判断资源是否更新。如果资源未更新,服务器返回 304 状态码,浏览器继续使用本地缓存;如果资源已更新,服务器返回 200 状态码和新资源。
1. 实现方式
协商缓存通过以下两种 HTTP 头实现:
-
Last-Modified和If-Modified-Since:Last-Modified:服务器返回资源时,携带资源的最后修改时间。- 例如:
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT。
- 例如:
If-Modified-Since:浏览器再次请求时,携带上次的Last-Modified值,服务器通过比较时间判断资源是否更新。- 如果资源未更新,返回 304 状态码;否则返回 200 和新资源。
-
ETag和If-None-Match:ETag:服务器返回资源时,携带资源的唯一标识(通常是哈希值)。- 例如:
ETag: "123456789"。
- 例如:
If-None-Match:浏览器再次请求时,携带上次的ETag值,服务器通过比较标识判断资源是否更新。- 如果资源未更新,返回 304 状态码;否则返回 200 和新资源。
2. 协商缓存流程
- 强缓存失效后,浏览器向服务器发送请求。
- 服务器根据
If-Modified-Since或If-None-Match判断资源是否更新。 - 如果资源未更新,返回 304 状态码,浏览器使用本地缓存。
- 如果资源已更新,返回 200 状态码和新资源。
3. 优点
- 减少带宽消耗,避免重复传输未更新的资源。
- 适用于频繁更新的资源。
三、强缓存与协商缓存的区别
| 特性 | 强缓存 | 协商缓存 |
|---|---|---|
| 是否发送请求 | 不发送请求,直接使用缓存 | 发送请求,服务器判断是否使用缓存 |
| 状态码 | 200(from cache) | 304(Not Modified) |
| 实现方式 | Expires、Cache-Control | Last-Modified、ETag |
| 适用场景 | 静态资源(长期不变) | 动态资源(可能更新) |
四、缓存策略的最佳实践
-
静态资源:
- 使用强缓存,设置较长的
max-age(如一年)。 - 通过文件名哈希(如
main.a1b2c3.js)实现缓存更新。
- 使用强缓存,设置较长的
-
动态资源:
- 使用协商缓存,确保资源更新后客户端能及时获取最新版本。
-
禁用缓存:
- 对于敏感数据或实时性要求高的资源,使用
Cache-Control: no-store。
- 对于敏感数据或实时性要求高的资源,使用
通过合理配置强缓存和协商缓存,可以显著提升网页性能,同时减少服务器负载。