什么是浏览器缓存
浏览器的缓存机制,也就是我们常说的http缓存,在前端性能优化中,缓存是非常重要的一环。合理的利用缓存,可以试我们的页面加载更快速,性能更好。
1.强缓存
当我们访问一个url命中强缓存后,浏览器会直接返回200状态码和相应内容,不会向服务端发起请求。
Expires
expires是HTTP1.0的产物,值为一个时间戳,准确来讲是格林尼治时间,服务器返回该请求结果缓存的到期时间。再次发送请求时,如果未超过过期时间,直接使用该缓存,如果过期了则重新请求。
expires判断是否过期是用本地时间来判断的,本地时间是可以自己修改的,所以通过expires设置过期时间可能不准。
Cache-Control
Cache-Control是HTTP1.1的产物,主要取值如下:
public:响应可以被对象(包括:发送请求的客户端、代理服务器)等等,即使是通常不可缓存的内容。(例如:1.该响应没有max-age或Expires消息头;2.该响应对应的请求是POST)private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。no-cache:在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。no-store:缓存不应存储有关客户端请求和服务器响应的任务内容,即不使用任何缓存。max-age:设置缓存的最大生命周期,超过这个时间即过期,单位是秒。与Expires不同,max-age使用的是相对时间,更加准确。mast-revalidate:一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源详情后续请求。
Expires使用绝对时间,而本地时间可能不准。Cache-Control的max-age使用相对时间,单位是秒。当Expires和max-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
Etag:Etag类似于文件的指纹,只有文件的内容发生变化时才会变更。用来判断文件是否被修改过,由于精度更高,优先级高于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 Worker是PWA的重要实现机制
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 Cache与Disk Cache两者的对比:
- 比较大的
JS、CSS文件会被丢硬盘中存储,反之则存储在内存中 - 当前系统内存使用率比较高的时候,文件优先进入磁盘
Push Cache
Push Cache是HTTP/2中的内容,也是浏览器缓存的最后一段防线,当以上三种缓存都没有命中的时候,它才会被使用。
我所知道的,它只会在会话(Session)中存在,一旦会话结束它就会被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟。特点如下:
- 所有的资源都能被推送,并且能够被缓存,
Edge和Safari浏览器支持相对比较差 - 可以推送
no-cache和no-store的资源 - 一旦连接被关闭,
Push Cache就被释放 - 多个页面可以使用同一个
HTTP/2的连接,也就可以使用同一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接。 Push Cache中的缓存只能被使用一次- 浏览器可以拒绝接受已经存在的资源推送
- 你可以给其他域名推送资源