缓存可以说是性能优化中简单高效的一种优化方式了,一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,
并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
数据请求的步骤:发起网络请求,后端处理,浏览器响应。
浏览器缓存在第一步网络请求和浏览器响应2个环节中做性能优化。
缓存位置:
service worker:运行在浏览器背后的独立线程,一般可以用来实现缓存功能,
。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。service workder的缓存与浏览器其余内建缓存不同,它可以让我们
控制缓存哪些文件,如何匹配缓存,如何读取缓存,并且缓存是持续性的
2.memory cache
memory cache也是内存中的缓存,主要包含的是当前页面中已经抓取到的资源,例如页面上已经下载好的样式,脚本等,
读取内存中的数据肯定比磁盘来得快,内存读取高效,可是缓存持续性很低,会随着进程的释放而释放,
一旦关闭tab页面,内存中的缓存也就被释放了.
内存缓存在缓存资源时并不关心返回的资源的http缓存头cache-control是什么,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。
3.disk cache 顾名思义也就是硬盘中的缓存,读取速度较低,但是什么都可以存储到磁盘中,,比之 Memory Cache 胜在容量和存储时效性上。
对于大文件来说,大概率是不会存储在内存中的,反之优先,
当前系统内存使用率高的话,文件优先存储进硬盘中.
4.push cache是http/2中的内容,当以上3种缓存都没有命中的时候,才会被使用,只在会话session中使用,一旦会话session结束,也就被释放,并且缓存时间很短。
出于对性能的考虑,有的浏览器会对相同域名但不同的tab标签使用同一个http连接。
大部分的接口都应该选择好缓存策略,通常浏览器缓存策略分为2种,强缓存和协商缓存,
并且缓存策略都是通过设置http header来实现的。
浏览器与服务器通信为应答模式,浏览器发出http请求,服务器响应后拿到数据,
浏览器如何确定一个资源该不该被缓存,如何去缓存呢。
浏览器第一次向服务器发起请求后拿到请求结果后,将请求结果和缓存标识存入浏览器缓存中,
浏览器每次发出请求,都会现在浏览器缓存中查找请求的结果以及缓存标识,浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览
器缓存中
确保了每个请求的缓存存入与读取,
是否需要向服务器重新发起http请求将缓存分为2个部分,分别是强缓存和协商缓存
强缓存:不会向服务器发送请求,直接从缓存中读取资源,强缓存通过设置2种http header来实现,
expires 和 cache-control.
expires:用来指定资源到期的时间,是服务器端的具体的时间点,
expires = max-age + 请求时间,。需要和last-modified结合使用,
是web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器都可以直接从浏览器缓存中读取数据,而无需再次请求。
cache-control主要用来控制网页缓存,cache-control:max-age=300,则代表在这个请求正确返回时间,5分钟内再次加载该网页,就会命中强缓存,cache-control可以在请求头或者响应头中设置。
expires是http1.0的产物,cache-control是http1.1的产物,同时存在,cache-control优先级高于expires.
expires是一个过期的产物,现阶段它的存在只是一种兼容性的写法。
强缓存判断是否缓存的依据是是否超出某个时间或者某个时间段,而不用去关心服务器端的数据是否跟新了.
可能导致加载文件不是服务器端最新的文件,那我们如何得知服务器端内容是否已经发生了更新呢这时候就要用到协商缓存。
5.协商缓存。
协商缓存是强缓存失效后,浏览器携带着缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,,
主要有以下情况,
协商缓存生效,返回304和not modified
协商缓存失效,返回200和请求结果
协商缓存可以通过设置http header来实现,last-modified和if-modified-since.
浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加last-modifed的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;
last-modifed是文件在服务器上的最后修改时间。
浏览器下一次请求资源时,浏览器首先检测有last-modified这个header,于是添加if-modified-since这个header,值就是last-modified中的值,服务器收到资源后,会根据if-modified-since中的值和服务器中的最后修改时间作比较,如果没有变化,就返回304和空的响应体,直接读取缓存,如果If-Modified-Since的时间小于浏览器的最后修改时间,说明文件有更新,于是返回新的资源文件和200.
如果本地打开了缓存文件,即时没有修改文件,也会造成last-modified被修改,服务器不能命中缓存导致发送相同的资源。
既然根据文件修改时间来决定是否缓存尚有不足,能否根据文件内容是否修改来决定缓存策略?所以在 HTTP / 1.1 出现了ETag和If-None-Match.
ETag是服务器响应请求时,返回当前资源文件的一个唯一标示,(由服务器生成),只要资源有变化,ETag就会重新生成,浏览器在下一次加载资源并向服务器端发送请求时,,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传过来的if-none-match和自己服务器上的etag标签是否一致即可。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
etag优于last-modified
强缓存优于协商缓存进行。,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存有服务器决定是否使用缓存**,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。
用户行为对浏览器缓存的影响:指的是用户在浏览器操作时,会触发怎样的缓存策略。
打开网页:直接输入地址,查找disk cache中是否有匹配。。如有则使用;如没有则发送网络请求。
普通刷新(f5),因为tab并没有关闭,因此memory cache是可用的,会被优先使用,其次才是disk cache.
强制刷新(ctrl + f5),浏览器不使用缓存,存,因此发送的请求头是:cache-control:no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。