缓存
Web 缓存可以分为浏览器缓存、CDN 缓存、服务器缓存和数据库数据缓存这四种。其中,跟前端密切相关的是浏览器缓存。使用缓存是为了加快网页打开速度,减少网络带宽消耗,降低服务器压力等。
浏览器缓存分为强缓存和弱缓存,它们的区别是:如果强缓存命中,则不会向服务器发送请求;弱缓存一定会发送请求到服务器,通过资源的请求首部字段验证是否命中弱缓存,在命中时服务器会将请求返回但不会返回该资源的实体,而是通过 304
这个状态码告知浏览器可以从缓存中加载这个资源。
上述过程的简略流程图为:
缓存策略
浏览器如何去缓存由 HTTP 报文的首部决定:
强缓存
强缓存又称「本地缓存」。
控制强缓存的报文首部字段按照优先级排列为:
字段 | 说明 |
| 在响应报文中设置为 |
| 见下表 |
| 指定了一个日期/时间,在这个时间/日期之前,HTTP 缓存被认为是有效的。 |
Cache-Control
与浏览器缓存相关的值主要有:
值 | 说明 |
| 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。响应只作为私有的缓存,不能被CDN等缓存。如果要求HTTP认证,响应会自动设置为private。 |
| 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。表明响应可以被浏览器、CDN等等缓存。 |
| 缓存前必需确认其有效性。表示请求必须先与服务器确认缓存的有效性,如果有效才能使用缓存(弱缓存),无论是响应报文首部还是请求报文首部出现这个字段均一定不会命中强缓存。Chrome硬性重新加载(Command+shift+R)会在请求的首部加上 |
| 不缓存请求或响应的任何内容。表示禁止浏览器以及所有中间缓存存储任何版本的返回响应,一定不会出现强缓存和弱缓存,适合个人隐私数据或者经济类数据。 |
| 响应的最大值,单位为 |
弱缓存
弱缓存又称「协商缓存」。
控制弱缓存的报文首部字段按照优先级排列为:
ETag
/If-None-Match
Last-Modified
/If-Modified-Since
缓存位置
浏览器缓存位置分为四种,其优先级顺序如下:
Service Worker
Memory Cache
Disk Cache
Push Cache
当上述四个缓存位置中的缓存都没有命中时,则会向服务器发起请求。
在 Chrome 浏览器中查看「Network」信息时会发现,「Size」那栏有的请求会显示 from disk cache
或 from memory cache
。在 Chrome 扩展程序的 API 文档的 chrome.webRequest
中有相关描述:
Chrome employs two caches — an on-disk cache and a very fast in-memory cache. The lifetime of an in-memory cache is attached to the lifetime of a render process, which roughly corresponds to a tab. Requests that are answered from the in-memory cache are invisible to the web request API. If a request handler changes its behavior (for example, the behavior according to which requests are blocked), a simple page refresh might not respect this changed behavior. To make sure the behavior change goes through, call
handlerBehaviorChanged()
to flush the in-memory cache. But don't do it often; flushing the cache is a very expensive operation. You don't need to callhandlerBehaviorChanged()
after registering or unregistering an event listener.
具体是什么机制尚未得知,知乎有相关问题。
Service Worker
Service Worker 是一个注册在指定源和路径下的事件驱动 worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。 我们可以通过谷歌开发者工具中的 Application -> Service Workers 查看当前缓存的资源。
Memory Cache
Memory Cache 即内存中的缓存,其特点是容量小、读取高效、持续性短,会随着进程的释放而释放。 所以,在内存使用率低、缓存小尺寸资源时,会以 Memory Cache 为优先,否则使用 Disk Cache。
Disk Cache
Disk Cache 即磁盘中的缓存,其特点是容量大、读取缓慢、持续性长,任何资源都能存储到磁盘中。 所以,在内存使用率高、缓存大尺寸资源时,会以 Disk Cache 为优先。
Push Cache
Push Cache 是 HTTP 2.0 中的内容,其缓存时间也很短暂,只在会话(Session)中存在,一旦会话结束就被释放。
更新缓存
想不修改文件路径去更新缓存是不可能的,因此要通过更新 URL 中的查询字符串或者文件名中的指纹来实现缓存的更新。
总结
浏览器获取网络资源的完整流程为: