浏览器缓存机制
简介
浏览器缓存是Web性能优化的核心手段之一,它能显著减少网络请求,提高页面加载速度
缓存位置与层级
-
内存缓存
- 存储在RAM中,读取速度最快
- 生命周期与标签页共存,关闭标签即清除
- 通常存储较小资源(如CSS、JS、图片)
-
Server Worker缓存
- 可离线访问
- 缓存持久化,需要手动清除
-
Disk Cache (硬盘缓存)
- 存储在硬盘上,容量较大
- 持久化缓存,关闭浏览器仍存在
- 存储较大文件(如视频、大图)
-
Push Cache(HTTP/2推送缓存)
- HTTP/2 Server Push资源专用
- 会话级缓存,关闭即失效
- 优先级最低,其他缓存不可用时使用
缓存策略控制机制
打开浏览器控制台F12,从size这一列, 可以看到文件显示来自memory cache和dish cache的字样,表示文件从缓存中返回
浏览器缓存主要分为:强缓存和协商缓存
强缓存
特点:不请求服务器
通过以下HTTP头部控制,优先级从高到低:Cache-Control (HTTP/1.1),Expires (HTTP/1.0),Cache-Control高于Expires
Expires是HTTP 1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回,用GMT格式的字符串表示
问题:Expires是较老的强缓存管理header,由于它是服务器返回的一个绝对时间,在服务器时间与客户端时间相差较大时,缓存管理容易出现问题,比如:随意修改下客户端时间,就能影响缓存命中的结果
Cache-Control - 描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,所以相比较Expires,Cache-Control的缓存管理更有效,安全。
常用指令:
-
max-age=:缓存有效期(秒)
-
public:允许代理服务器缓存
-
private:仅浏览器可缓存
-
no-cache:需协商缓存验证
-
no-store:禁止任何缓存
-
immutable:资源永不变(指纹化资源)
协商缓存
Modified原理如下:
- 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上Last-Modified,这个header表示这个资源在服务器上的最后修改时间**
- 浏览器再次请求这个资源的时候,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值:
- 浏览器根据If-Modified-Since的header与服务器的文件判断文件时间是否发生变化,如果没有变化,则返回304状态码给浏览器,如果发生变化,则返回200状态码和最新的资源,并更新最新的Last-Modified
- 浏览器收到304则从缓存中获取资源
# 响应头
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
# 请求头
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
由于Modified并不是完全可靠,可能会发生资源发生了变化但是文件时间没有变化的情况,所以增加了ETag辅助验证
Etag/If-None-Match原理如下:
- 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上ETag属性,这是服务器根据当前请求的资源生成的唯一标识,这个唯一标识是一个字符串,只要资源有变化这个串就不同
- 浏览器再次跟服务器请求这个资源时,在request的header上加上If-None-Match的header,这个header的值就是上一次请求时返回的ETag的值
- 浏览器根据ETag的是否变化, 返回304或者200(正常返回资源)
# 响应头
ETag: "33a64df551425fcc55e4d42a148795d9"
# 请求头
If-None-Match: "33a64df551425fcc55e4d42a148795d9"
分强弱ETag检验:
- 强ETag:字节完全一致
- 弱ETag(W/前缀):语义一致即可
流程图
graph TD
A[资源请求] --> B{是否有缓存?}
B -->|否| C[直接请求服务器]
B -->|是| D{检查Cache-Control/Expires}
D -->|未过期| E[使用强缓存]
D -->|已过期| F[发送协商缓存请求]
F --> G{服务器验证资源}
G -->|未修改| H[304 Not Modified]
G -->|已修改| I[200 OK + 新资源]
H --> J[更新缓存头后使用缓存]
好处
- 减少页面加载时间,提高加载速度;
- 减少服务器负载,减少流量带宽;