简介
web缓存可大致分为:数据库缓存、服务器缓存、浏览器缓存;
浏览器缓存由分为:HTTP缓存、indexDB、localstoreage、cookie、pwa等
术语
- 命中缓存率:从缓存得到的数据和实际总的请求比率;
- 过期:超过设置的有效时间,此时获取内容从服务端获取,获取成功之后更新当前缓存;
- 验证:验证缓存中的内容是否有效,如果有效刷新过期时间;
- 失效:验证缓存内容失效,当内容变化时删除缓存内容 ;
浏览器缓存详解
浏览器缓存流程
首次请求:
再次请求:
浏览器缓存分为强缓存和协商缓存;
- 首先浏览器会根据发出请求的头信息中来判断是否命中强缓存,如果命中直接返回缓存数据,并且不会再往服务器发出请求
- 如果没有命中强缓存,会继续判断是否命中协商缓存,判断方式首先会发出请求到服务器,服务器会判断浏览器的缓存是否过期,如果没过期返回缓存
- 如果协商缓存也没有命中,服务器会把请求资源返回给浏览器,浏览器进行渲染;
强缓存
简述
强缓存请求是不会发送到服务器的,请求的返回码是200,但是size栏展示为from cache;是利用请求返回信息里面expires和cache-control两个字段共同确定的;
expires
主要表示过期截止时间点,需要和last-modified结合使用,如果时间没有到截止时间返回缓存信息; 不过有个明显的确定,它的参考时间是本地时间和服务器时间做对比,这样修改了本地时间就会出现错乱;于是出现了cache-control;
cache-control
cache-control是一个相对时间,表示一个时间范围,比如3600就是表示一个小时;这样就不会因为本地和服务器时间差异导致缓存错误;还有一点cache-control的优先级要高于expires
cache-control的几种取值:
- max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-- Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 * 60)天
- s-maxage 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。
- public 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。
- private 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。
- no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。
- no-store 禁止缓存,每次请求都要向服务器重新获取数据。
协商缓存
简述
协商缓存请求会发到服务器,服务器会根据请求的头信息中的last-modified或者Etag来判断是否命中协商缓存;如果命中则返回304码,浏览器从缓存拿取资源;
last-modified
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。
当第二次发出请求时候,发送请求中能获取到last-modified-since来判断是否命中缓存,如果命中则返回304,浏览器从缓存中获取资源;
但是还会出现和强缓存expires类似的问题,所以就出现了后续的Etag
Etag
Etag的话第二次请求返回是通过if-none-match来判断是否命中缓存;不过它最大的特点能保证每个资源都是唯一的,资源的变化会引起Etag的变化
Etag的变化依据由一下几点:
- 文件的编码i-node,此编码是Linux/unix用来识别文件的编码;
- 文件的修改时间
- 文件的大小
Etag相比last-modified的优点
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
总结
本文主要简述了浏览器的缓存策略,希望能给大家有一定帮助,不合适地方欢迎指出