浏览器缓存

144 阅读6分钟

什么是浏览器缓存

浏览器的缓存机制,也就是我们常说的http缓存,在前端性能优化中,缓存是非常重要的一环。合理的利用缓存,可以试我们的页面加载更快速,性能更好。

1.强缓存

当我们访问一个url命中强缓存后,浏览器会直接返回200状态码和相应内容,不会向服务端发起请求。

Expires

expiresHTTP1.0的产物,值为一个时间戳,准确来讲是格林尼治时间,服务器返回该请求结果缓存的到期时间。再次发送请求时,如果未超过过期时间,直接使用该缓存,如果过期了则重新请求。
expires判断是否过期是用本地时间来判断的,本地时间是可以自己修改的,所以通过expires设置过期时间可能不准。

Cache-Control

Cache-ControlHTTP1.1的产物,主要取值如下:

  • public:响应可以被对象(包括:发送请求的客户端、代理服务器)等等,即使是通常不可缓存的内容。(例如:1.该响应没有max-ageExpires消息头;2.该响应对应的请求是POST
  • private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。
  • no-cache:在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。
  • no-store:缓存不应存储有关客户端请求和服务器响应的任务内容,即不使用任何缓存。
  • max-age:设置缓存的最大生命周期,超过这个时间即过期,单位是秒。与Expires不同,max-age使用的是相对时间,更加准确。
  • mast-revalidate:一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源详情后续请求。

Expires使用绝对时间,而本地时间可能不准。Cache-Controlmax-age使用相对时间,单位是秒。当Expiresmax-age同时存在时,max-age的优先级更高。

2.协商缓存

顾名思义,协商缓存是指客户端跟服务器进行协商,确认缓存是否可用。

Last-Modified/If-Modified-Since

Last-Modified:标识服务端返回响应内容的最后修改时间,单位是秒,由于精度比Etag低,通常作为Etag的备用机制。

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

If-Modified-Since:浏览器进行协商缓存校验时,可以通过该字段将上次返回的Last-Modified的值发送给服务端,判断资源是否被修改。如果未修改,会返回304,否则服务器会将最新的资源返回,状态码为200

If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

Etag/If-None-Match

EtagEtag类似于文件的指纹,只有文件的内容发生变化时才会变更。用来判断文件是否被修改过,由于精度更高,优先级高于Last-Modified

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4

If-None-Match:服务器通过该字段判断内容是否改变,未改变时返回304状态码。如果内容有改变,返回修改后的内容,同时返回200状态码。优先级高于If-Modified-Since

If-None-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"

3.缓存位置

上面说过,如果命中强缓存,或者服务端返回了304状态码之后,浏览器可以使用缓存中的资源,这些资源的存放位置如下:

  • Serice Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

Service Worker

Service Worker是运行在浏览器后的独立线程,脱离了浏览器窗体,无法直接操作DOM,可以实现离线缓存网络代理等功能,主要特点如下:

  • Web Worker类似,运行于独立的线程
  • 使用Service Worker会涉及到请求拦截,需要HTTPS来保证安全性,传输协议必须是HTTPS
  • 与浏览器其它内建的缓存机制不同, 它可以让我们自由的控制缓存哪些文件、如何匹配读取缓存, 且缓存是持续性的
  • Service WorkerPWA的重要实现机制

Memory Cache

Memory Cache是内存中的缓存,主要存储页面已经获取到的样式脚本图片等资源,特点如下:

  • 读取效率快,但是缓存持续的时间短,会对着进程的释放而释放,也可能因为内存空间占用多而释放。
  • 几乎所有的请求都能进入Memory Cache
  • Memory Cache中读取缓存时,浏览器会忽略Cache-Control中的max-age、no-cache等头部配置,除非设置了no-store这个头部配置

Disk Cache

Disk Cache,也叫做HTTP Cache,是存储在硬盘上的缓存,所以它是持久存储,存在于文件系统中
效率上比Memory Cache慢,但是胜在存储容量大,存储时间长。
在所有浏览器缓存中,Disk Cache是覆盖面最大的。它会根据前面我们提到的HTTP header中的缓存字段来判断哪些资源需要缓存,哪些资源不需要请求而直接使用,哪些已经过期了需要重新请求获取。

Memory CacheDisk Cache两者的对比:

  • 比较大的JS、CSS文件会被丢硬盘中存储,反之则存储在内存中
  • 当前系统内存使用率比较高的时候,文件优先进入磁盘

Push Cache

Push CacheHTTP/2中的内容,也是浏览器缓存的最后一段防线,当以上三种缓存都没有命中的时候,它才会被使用。 我所知道的,它只会在会话(Session)中存在,一旦会话结束它就会被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟。特点如下:

  • 所有的资源都能被推送,并且能够被缓存,EdgeSafari浏览器支持相对比较差
  • 可以推送no-cacheno-store的资源
  • 一旦连接被关闭,Push Cache就被释放
  • 多个页面可以使用同一个HTTP/2的连接,也就可以使用同一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接。
  • Push Cache中的缓存只能被使用一次
  • 浏览器可以拒绝接受已经存在的资源推送
  • 你可以给其他域名推送资源