浏览器缓存
缓存机制
- 每次请求前都会先在浏览器缓存中查找该请求的结果以及缓存标识
- 每次请求返回后都会将请求结果和缓存标识存入浏览器缓存中
缓存策略
强缓存、协商缓存
缓存类型
根据缓存位置分为四种,优先级从高到低,浏览器依次查找且都没有命中时会重新请求
- Service Worker,传输协议必须为 HTTPS
- Memory Cache(常见),内存虽读取快,但容量小,所以一般会随着进程的释放而释放
- Disk Cache(常见),容量大,但读取较慢,会根据 HTTP HEADER 中的字段判断资源是否需要缓存
- Push Cache,只在会话(Session)中存在,一旦会话结束就被释放
资源缓存位置
- 对于大文件来说,大概率存在硬盘中,反之存在内存中
- 当前系统内存使用率高的话,文件优先存储进硬盘
强缓存
从缓存中读取资源,状态码 200,Size 显示 from disk cache 或 from memory cache
强缓存相关头部字段
强缓存可以通过设置两种 HTTP Header 实现:
- Cache-Control:控制网页缓存,优先级高于 Expires(HTTP 1.1)
- Pragma: 同上,用于向后兼容 HTTP 1.0
- Expires:缓存过期时间(HTTP 1.1)
meta 标签也可以设置
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
Cache-Control 常用请求指令
- no-store,不缓存资源
- no-cache,资源被缓存,浏览器使用缓存时会确认一下数据是否还跟服务器保持一致
- max-age=30,缓存将在 30s 内失效
- max-stale=30,客户端可以接受过期 30s 内的资源
- min-fresh=30,再过 30s 就会过期的缓存资源希望服务器重新返回
- no-transform,Content-Encoding、Content-Range、Content-Type 等 HTTP 头不能由代理修改
- only-if-cached,客户端只接受已缓存的响应,且不向原始服务器检查是否有更新
Cache-Control 常用响应指令
- public,资源可被客户端和代理服务器缓存
- private,资源紧被客户端缓存
- no-store,不缓存资源
- no-cache,资源被缓存,浏览器使用缓存时会确认一下数据是否还跟服务器保持一致
- max-age=30,缓存将在 30s 内失效
- s-maxage=30,与 max-age 作用一样,但只在代理服务器中生效
- no-transform,Content-Encoding、Content-Range、Content-Type 等 HTTP 头不能由代理修改
- must-revalidate,一旦资源过期,在成功向服务器重新验证之前,该资源缓存不可用
- proxy-revalidate,作用同上,适用于代理服务器
协商缓存
协商缓存就是强缓存不生效的情况下,浏览器携带缓存标识向服务器发起请求,服务器根据缓存标识决定是否使用缓存。协商缓存两种结果:
- 协商缓存生效,返回 304 和 Not Modified
- 协商缓存不生效,返回 200 和请求结果
协商缓存相关请求头
- Last-Modified 和 If-Modified-Since(HTTP 1.0) 过程:第一次访问资源时,服务器会在响应头中添加 Last-Modified,值是该资源在服务器上的最后修改时间,之后浏览器会缓存该资源和响应头;下一次请求这个资源时,浏览器检测到有 Last-Modified,会在请求头中添加 If-Modified-Since,服务器会对比该值与资源在服务器中的最新修改时间,若时间不一致,说明该资源有更新 弊端:本地打开缓存文件会修改 Last-Modified;Last-Modified 精度为秒以至于 1s 内的连续修改无法识别
- ETag 和 If-None-Match(HTTP 1.1) 过程:同上,只不过把最后修改时间改为根据内容计算的唯一标识(hash),与上面同时存在的话浏览器会优先考虑 ETag 弊端:性能上可能没有上面的好, 因为服务器要计算 hash
浏览器默认缓存策略
如果什么缓存策略都没设置,浏览器通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间