你有没有发现,有些网页第二次打开速度特别快?这就是利用了缓存。 下面介绍一下浏览器常见的两种缓存策略。
一:强缓存
强缓存的本质是 "时间有效性验证",浏览器无需向服务器发送请求,直接根据本地缓存的过期时间判断是否可用。
假设项目中有一张图片资源:test.png。 首次请求test.png时,服务器返回Cache-Control: max-age=86400(24 小时有效期)。 24 小时内再次请求该图片,浏览器直接从缓存读取,网络请求瀑布图显示200OK ,不会向服务器发送请求(200仅仅表示资源加载成功,并未与服务器交互)。
强缓存类型:
1.from memory cache (资源暂存于浏览器内存)
2.from disk cache ( 资源持久化存储于本地硬盘)
关键http头部字段
Expires (单位:GMT 时间字符串)
格式:Expires: Wed, 03 Jun 2025 12:00:00 GMT
缺点:依赖服务器时间,若客户端与服务器时钟不同步,服务器返回的过期时间就不一定是准确的,可能导致缓存提前失效或过期资源被使用。
Cache-Control(单位:秒)
max-age=604800:7 天有效期,优先级高于 Expires。
Cache-Control其他值:
public:允许代理服务器缓存(如 CDN)
private:仅客户端可缓存
no-cache:非禁止缓存,而是要求使用前必须经服务器验证(实际触发协商缓存)
no-store:严格禁止缓存,每次请求必须从服务器获取
Cache-Control与Expires的优先级对比
Cache-Control
的优先级高于 Expires
。
原因:
Expires
通过 "具体时间点" 定义过期(如 Wed, 31 Dec 2025 23:59:59 GMT
),但它依赖浏览器本地时间,
Cache-Control
的 max-age
以 "时长" 定义过期(如 max-age=86400
表示 1 秒),计算起点是 "资源首次下载完成的时间",不依赖本地时间
Cache-Control
优先级高于 Expires
,核心是它解决了 Expires
依赖本地时间的缺陷。
强缓存工作流程
浏览器发起资源请求 -> 服务器返回资源,并设置缓存 -> 再次发送资源请求 ->检查是否过期 →->未过期 (不存在缓存 或 已过期 → 发起网络请求) -> 返回200(不发送网络请求)
如果资源命中值强缓存,如何更新?
改变资源唯一标识,加版本号、改变资源hash值...
二 : 协商缓存
1、触发条件与核心逻辑
当强缓存失效(如 max-age 过期),浏览器会向服务器发送请求,携带缓存标识验证资源是否更新。
2、双重验证机制
第一重:Last-Modified / If-Modified-Since
服务器响应时添加Last-Modified: Thu, 01 Jun 2025 10:00:00 GMT
浏览器再次请求时,在请求头中携带If-Modified-Since: Thu, 01 Jun 2025 10:00:00 GMT
服务器对比资源实际修改时间,若未变更则返回304 Not Modified,浏览器使用本地缓存
第二重:ETag / If-None-Match(优先级更高)
服务器根据资源内容生成唯一哈希值,如ETag: "5f8e1a2b3c4d5e6f"
浏览器请求时携带If-None-Match: "5f8e1a2b3c4d5e6f"
服务器对比哈希值,一致则返回 304,否则返回新资源(200 OK)
3、协商缓存两种方式优先级说明
为什么ETag 的精度高于 Last-Modified?
1.某些场景下资源修改时间变更但内容未变(如修改注释)Last-Modified 会误判为更新;
2.因为Last-Modified的最小单位是秒,加入文件在一秒内改变了多次,这个时候Last-Modified的值并没有变化。
ETag 基于内容哈希,只要内容不变,即使修改时间变化也能正确识别为未更新。
协商缓存的304/200,均为服务器返回。
三、协商缓存与强缓存优先级
强缓存优先级高于协商缓存
原因:本质是为了最大化减少网络请求,提升加载性能