随着浏览器功能的日益强大,在工作中,浏览器是前端工程师们最重要的战友和开发调试工具,它承载着用户最舒适的用户体验,ui最佳的设计成果展示,后台数据最直观的展示。因此,对浏览器的认识和理解起到举足轻重的地位,现学习浏览器的缓存知识分享如下,欢迎各位
整个web应用简易流程如下图:
上述流程,哪些地方比较耗费时间
缓存在很多地方都有运用
整个浏览器的缓存基本过程如下图:
从缓存的位置来说,分为四种,并且各有优先级,每次请求依次查找都没有才会去请求网络。
Service Worker(手动)
运行在浏览器背后的独立线程,一般用来实现缓存功能。类似于一个代理服务器
传输协议必须是https,因为Service Worker中涉及到请求拦截,所以必须用HTTPS来保障安全。
使用方法:注册–> 监听install事件–>缓存需要的文件
Memory Cache(自动)
内存中的缓存,读取速度快
内存容量小,关闭tab页面,内存中的缓存也就释放了。
Disk Cache (自动)
硬盘上的缓存,读取速度比内存缓存慢
时效性和容量大大优于 Memory Cache
浏览器会自动的根据HTTP Header中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期了需要重新请求。
浏览器会自动进行清理,算法会把最老的资源删除。
Push Cache
推送缓存。http/2(2015)中新增的内容
当以上三种缓存都没有使用才会被使用到
所有的资源的资源都会被推送,并且能够被缓存,但是Efge和safari浏览器支持相对较差。
可以推送no-cache和no-store的资源
一旦连接被关闭,Push Cache 就被释放
多个页面可以使用同一个HTTP/2的连接,也就可以使用同一个Push Cache,这主要还是依赖浏览器的实现而定,出于对性能的考虑没有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接
pushCache的缓存只能被使用一次
浏览器可以拒绝接收已经存在的资源推送
你可以给其他域名推送资源
分为 强制缓存 和 协商缓存
【注意】 无论是强制缓存还是协商缓存都是DiskCache或者叫做HTTPCache的一种
客户端发送请求,先访问缓存,有则返回,没有则请求服务器,响应再缓存
强制缓存减少请求数,是提升最大的缓存策略,
可以造成强制缓存的字段是 Cache-control 和 Expires
Expires
这是HTTP1.0的字段,表示缓存到期时间(绝对时间【当前时间+缓存时间】)
Expires:Thu,10 NOV 2017 08:11:33 GMT
在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。
缺点:字段设置多个空格,少个字母,都会导致变为非法字符属性从而导致失效。时差和客户端修改时间也会导致缓存失效,所以不好用。
Cache-control
自从HTTP/1.1开始,Expires逐渐被Cache-control取代。
在http/1.1中,增加了该字段,该字段表示资源缓存的最大有效时间,在该时间内,用户不需要向服务器发送请求。
Cache-control是一个相对时间,即使客户端时间发生改变,相对时间也不会随之改变,这样可以保持服务器和客户端的时间一致性,而且Cache-control的可配置型比较强大,Cache-control的优先级高于Expires。
Cache-control设置的是相对时间:
Cache-control:max-age=2592000
Cache-control里的属性
可混用有优先级,例如:
Cache-control:public,max-age=259200
为了兼容http1.0和http1.1,实际项目中Cache-control和Expires都会设置
强制缓存(强制时间内使用缓存)失效,比如max-age到期了,就要使用协商缓存(客户端向服务器发送请求,携带资源标识,服务器会把资源标识和服务器做对比,如果资源没发生改变,服务器就会返回304,告诉客户端资源无更新,客户端会继续使用缓存,如果资源有改变,服务器返回新的数据、缓存规则、200的code码,浏览器将新的规则写入缓存),由服务器决定缓存内容是否失效。
协商缓存的主要优化主要体现在响应上通过减少响应体体积,来缩短网络传输时间,所以强制缓存比提升幅度较小,但总比没有缓存好
协商缓存是可以强制一起使用的,作为在强制缓存失效后的一种后背方案。
协商缓存里的对比方式
Last-Modified & If-Modified-since
1.服务器通过Last-Modified字段告知客户端,资源最后一次被修改的时间
2.浏览器将这个值和内容一起记录在缓存数据库中
3.下一次请求相同的资源,浏览器会从自己的缓存中找到"不确定是否过期"的缓存,因此在请求头中将Last-Modified的值写入到请求头的If-Modified-since字段
4.服务器会将If-Modified-since的与last-modified的字段进行对比,如果相等,则表示未修改,响304,反之,则表示修改了,响应200状态码,并返回数据
缺陷:1.资源更新的速度是毫秒,那么该缓存是不能被使用的,因为它的时间单位最低是秒
2.文件如果是服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
所以http/1.1出现了 Etog & If-None-Match
Etog & If-None-Match
1.Etog存储的是文件的特殊标识(一般是一个hash值),服务器存储着文件的etog字符
2.浏览器请求资源,服务端返回资源和一个Elag
3.下一次请求,强缓失败,带着elog来找服务器要资源,即此在请求头中将elog写入到请求头的If-None-Match字段
4.资源未更新,返回304状态码
当浏览器请求资源时:
从Service Worker中获取内容(如果设置了Service Worker)
查看Memory Cache
查看Disk Cache。这里又细分:
发送网络请求,等待网络响应
把响应的内容"自动"存入DiskCache(如果HTTP响应头有相应配置的话)
把响应内容的引用"自动"存入MemoryCache(无视http头信息的配置)
把响应内容存入Service Worker 的Cache Storage(如果设置了Service Worker)
用户对浏览器的不同操作,会触发不同的缓存读取策略
对于经常发生变化的资源,可以再响应头设置 Cache-control:no-cache ,使浏览器每次都请求服务器,配合ETog(比对hash)或Lat-Modified(比对时间戳)来验证资源是否有效。
这样的做法虽然不能节省请求的数量,但是因为服务端资源无变化,比对成功,服务端就会返回304,所以会减少请求的数据大小,不用每次都返回200和数据。
再处理这类资源,通常会配置一个很大的max-age=31536000(一年),这样浏览器之后请求相同的URL会命中强制缓存。
为了解决更新的问题,就需要在文件名(或者路径)中添加Hash,版本号等动态字符,从而达到更改URL的目的,由于这样设置会使请求的资源不同,所以强制缓存也就不再使用,浏览器会重新发送请求,进入协商缓存。