浏览器——缓存机制
浏览器的缓存机制就是将一家在过的资源(如 HTML、CSS、JS、图片、字体等)临时存储在本地设备中,当再次访问同一页面时,优先从本地读取资源,而非重新从服务器下载。缓存机制可以提升加载速度,减少流量消耗。
一、缓存的位置:内存、硬盘、Service Worker、Push Cache
浏览器缓存优先级从高到低依次为:
Memory Cache(内存缓存)
Disk Cache(硬盘缓存)
Service Worker Cache(服务工作线程缓存)
Push Cache(推送缓存)。
缓存类型 | 存储位置 | 读取速度 | 存储时长 | 特点 |
内存缓存 | 浏览器内存 | 最快 | 短暂(关闭标签页即清空) | 容量小,优先存储 “临时高频资源”,(如 JS、CSS) |
硬盘缓存 | 本地硬盘 | 较快 | 持久(按规则过期) | 容量大,长期存储 “非临时资源”,(图片、字体、HTML) |
service线程缓存 | 独立线程控制的硬盘区域 | 中等 | 开发者自定义 | 可编程控制,支持离线访问 |
推送缓存 | 浏览器临时缓存 | 快 | 极短(会话结束清空) | 兼容性低(仅支持 HTTP/2),优先级最低 |
内存缓存的地方是运行时计算机分配给浏览器的空间,硬盘缓存的地方是浏览器相关资源存储的空间。
二、缓存的形式
浏览器会为每个缓存资源建立一套 “索引体系”,确保下次请求时能快速匹配并读取缓存规则:
资源标识:请求的 URL(含查询参数,如 https://xxx.com/style.css?v=1.0)
缓存元数据(Headers):就是 Cache-Control、Expires、ETag、Last-Modified 这些字段,以及其他辅助字段(如 Content-Type、缓存时间戳等),单独存储为 “元数据文件” 或 “索引记录”。
资源内容:服务器返回的资源本体(如 CSS 、图片二进制数据、JS 等),通常会压缩或加密存储。
三、缓存的策略
浏览器通过 HTTP 协议头字段的规则来判断“是否使用缓存”“缓存是否过期”,优先级从高到低是:强缓存、协商缓存。
3.1 强缓存:直接从本地读取缓存,不发请求
强缓存是优先级最高的缓存策略。
浏览器会先检查本地缓存的“过期时间”,若未过期则直接使用本地资源,不向服务器发送任何请求(Network 面板中资源状态为 200 OK (from disk cache) 或 (from memory cache))。
控制强缓存的 HTTP 头字段有两组(优先级:Cache-Control > Expires):
① Cache-Control(HTTP/1.1,主流):通过多个指令组合控制缓存。
private:仅允许浏览器缓存,禁止 CDN、代理等中间节点缓存(用户个性化资源,如登录后的页面)。
no-store【优先级最高】:禁止存储任何副本和验证信息,导致强缓存和协商缓存不能发生。每次都需从服务器重新下载(如支付页面、实时数据页面)。
② Expires(HTTP/1.0,兼容性字段)
指定缓存的绝对过期时间,例如 Expires: Wed, 21 Oct 2024 07:28:00 GMT。
缺陷:依赖本地设备时间,若用户修改系统时间,可能导致缓存提前过期或失效。
3.2 协商缓存:先问服务器,再决定是否用缓存
当强缓存过期或资源设置了no-cache时,就会触发“协商缓存”的策略。
浏览器发送的请求会带【相应标识】,由服务器判断本地缓存是否仍有效:
控制协商缓存的 HTTP 头字段有两组(优先级:ETag / If-None-Match > Last-Modified / If-Modified-Since):
① ETag / If-None-Match(基于资源内容判断,但服务器生成哈希值会消耗少量性能)
② Last-Modified / If-Modified-Since(以秒为单位,若资源在 1 秒内多次修改,无法识别)
四、缓存的生命周期
4.1 首次请求资源:
浏览器无本地缓存,直接向服务器发送请求。
服务器返回资源 + 缓存规则(Cache-Control/Expires、ETag/Last-Modified)。
浏览器存储资源到本地(根据资源类型存入 Memory Cache 或 Disk Cache),并记录缓存规则。
4.2 判断强缓存(有效优先级Cache-Control>Expires,存储优先级Memory Cache>Disk Cache)
max-age/Expires有效,检查Memory Cache是否存在资源,有则使用Memory Cache(如刚关闭又重新打开的标签页)。没有则检查Disk Cache是否存在资源,有则使用Disk Cache。
4.3 判断协商缓存(有效优先级ETag/If-None-Match > Last-Modified/If-Modified-Since)
若Disk Cache不存在或Cache-Control/Expires失效(即强缓存无效),触发协商缓存,向服务器发送带If-Modified-Since/If-None-Match的请求。
服务器判断协商缓存结果:
有效(资源未变):返回304 Not Modified,浏览器继续使用 Disk Cache。
无效(资源已变):返回200 OK+ 新资源 + 新缓存规则,浏览器更新 Disk Cache。
4.4 没有缓存则重新下载资源
若以上缓存均无,直接从服务器下载新资源,重复 “首次请求” 的存储流程。
- 五、常见缓存问题
五、缓存失效的各种场景
5.1 资源更新
- 资源内容更新,对应的缓存标识(ETag 或 Last-Modified)会改变,导致协商缓存失效。
- 资源URL变化,则强缓存也会失效。
5.2 缓存过期
强缓存的max-age过期(没有设置max-age时expires也过期)。触发协商缓存,ETAG有变化(没有设置ETAG时last-modified也过期)。服务器返回200+新资源+新缓存规则。
5.3 设置了禁止缓存规则
强缓存Cache-Control设置了max-age=0 等效于 no-cache,max-age=0表示强缓存立即过期则触发协商缓存
强缓存Cache-Control设置了no-store 等效于完全禁止缓存,禁止存储所有副本。
5.4 last-modifie精度问题
5.5 浏览器行为
- 浏览器前进后退默认使用缓存
- 部分浏览器的隐私模式可能保留旧缓存
- 刷新页面时,缓存失效
F5 会忽略Memory Cache,并使Cache-Control: max-age失效,直接触发协商缓存
Ctrl+F5 会忽略所有缓存,直接下载新资源。
解决方案:Cache-control的immutable指令,确保未过期时即使刷新也不触发协商缓存。
