浏览器内部缓存存储
浏览器内部缓存存储分为 Memory Cache(内存缓存)和 Disk Cache(磁盘缓存),以及 Service Worker Cache API 的独立存储。
#tech / dev / frontend
#type / concept
#status / evergreen
#platform / browser
[!info] related notes
- 所属 MOC: 浏览器缓存体系
- 分类总览: 浏览器缓存分类与 304 / memory cache / disk cache
- 前置概念: 强缓存, 协商缓存
- 关联概念: Service Worker 与 Cache API
浏览器内部缓存存储
浏览器收到 HTTP 缓存响应后,实际存储到 Memory Cache 或 Disk Cache。
Memory Cache(内存缓存)
| 特性 | 说明 |
|---|---|
| 速度 | 最快 |
| 生命周期 | 随进程结束,通常当前标签页/进程内 |
| 跨进程 | 通常不跨 |
常用于:
- 页面内多次引用相同资源
- 短时间内重复访问某脚本
Disk Cache(磁盘缓存)
| 特性 | 说明 |
|---|---|
| 速度 | 比内存慢 |
| 生命周期 | 更持久 |
| 跨进程 | 可以跨页面、跨会话 |
内存/磁盘分配启发式
浏览器根据以下因素决定存储位置(基于 Chromium 行为,其他浏览器类似但不完全一致):
倾向存入 Memory Cache
- 小资源(JS、CSS、小图片)且正常加载
- 通过
<link rel="preload">加载的资源(为当前页面即将使用) - 同一渲染进程内的跨源资源可能共享内存缓存
倾向存入 Disk Cache
- 大资源(视频、大图片、字体)
- 通过
<link rel="prefetch">加载的资源(为未来导航准备) - CSS 解析器加载的资源(CSS 中引用的背景图、字体)
- 需要跨会话持久化的资源
[!warning] 这些是启发式规则,不是规范要求。不同浏览器实现不同,不能精确控制”这个资源一定进内存/磁盘”,只能控制缓存语义。
推测性预加载(Speculative Preloader)
HTML 解析器在解析过程中会扫描 <link>、<script>、<img> 等标签,提前发起资源请求。这些请求在 JS 执行之前就开始了,结果会进入 memory cache 或 disk cache。
这就是为什么第一次加载页面时,部分资源就已经在缓存中了——不是用户之前访问过,而是浏览器预判了需要哪些资源。
Prefetch Cache
通过 <link rel="prefetch"> 加载的资源存储在一个独立的”prefetch cache”中:
- 优先级较低,可能被更早淘汰
- Chrome DevTools 中 Size 列显示为
from prefetch cache - 主要用于预加载未来导航可能需要的资源
Service Worker Cache API 的独立存储
Service Worker 的 Cache API(caches.open())是独立于 HTTP 缓存的存储:
| 存储层 | 管理方 | 说明 |
|---|---|---|
| Memory Cache | 浏览器 | HTTP 缓存的内存层 |
| Disk Cache | 浏览器 | HTTP 缓存的磁盘层 |
| Cache Storage | Service Worker | 可编程缓存,caches.open() 管理 |
- Service Worker 可以拦截 fetch 请求,直接从 Cache API 返回响应,完全绕过 HTTP 缓存
- Service Worker 脚本文件本身存储在浏览器的内部缓存中,不在 Cache Storage 里
- 详见 → Service Worker 与 Cache API
浏览器如何决定
浏览器会根据以下因素综合决定存储位置:
- 资源大小
- 资源类型
- 是否常用
- 系统内存压力
- 缓存淘汰策略
不能精确控制”这个资源一定进内存/磁盘”,只能控制缓存语义。
开发者视角
在 Network 面板看到的状态:
200 from memory cache→ 内存缓存命中200 from disk cache→ 磁盘缓存命中from prefetch cache→ prefetch 缓存命中304 Not Modified→ 协商缓存命中200→ 网络请求
和 HTTP 缓存的关系
HTTP 缓存控制的是缓存语义(能否缓存、缓存多久、如何验证),实际存到 Memory 还是 Disk 由浏览器决定。