针对上一篇提到的server worker、memory cache、disk cache:
-
server worker是缓存位置独立,由开发者额外写的脚本,目前前端进行控制得情况几乎没有用,后续关注一下。
-
memory cache是前端无法控制的,因为他是浏览器用来优化性能,加快读取缓存速度的自我优化行为,不受http协议得约束。
-
前端来说,我们可以控制的只有disk cache,也就是HTTP cache,这其中分为强缓存、协商缓存、Cache-Control。
强缓存
当我们发出请求时,先访问缓存数据库是否存在,如果存在就直接返回数据及状态码200,如果不存在就继续下一步。
强缓存直接减少请求次数,是对性能提升最大的缓存策略。因为它可以覆盖请求-处理-响应得全步骤。
如何设置?按优先级排序是 Expires < Cache-Control
1.Expires:
http1.0,在响应头,告诉客户端资源失效的日期,失效之前就可以直接返回;
例如
Expires: Thu, 11 Jan 2023 11:11:11 GMT缺点:1、绝对时间,如果我们把客户端本地的时间修改一下,那么资源的失效时长就变了;2、写法太复杂了,容易出错;
2.cache-control:
http1.1,在通用首部字段,弥补了expires得缺点,告诉客户端资源最大有效时间,在有效时间内可以直接返回,这个是相对时间;
值可以混用,优先级从上到下如下:
cache-control: no-store;不缓存任何内容; cache-control: no-cache;还是会缓存这个内容,只是是否用要进行对比;(常用于经常变化的资源) cache-control: public;所有内容都可以被缓存(包括客户端、服务器、CDN等) privite;所有内容仅被缓存在客户端,代理服务器不可以缓存,默认值。 cache-control: max-age=2592000;最大有效时间(常用语不常变的资源,时间设置长一些,如果设置时间短,会引发js和css不是统一版本的问题,如果小网站或资源独立可以设置时间短) cache-control: must-revalidate;如果超过了max-age,浏览器必须向服务器发送请求,验证资源是否有效;协商缓存
当强缓存失效后,就会使用协商缓存,由服务器决定是否使用缓存;
浏览器先请求缓存数据库,返回缓存标识,之后浏览器拿到这个标识和服务器通讯,如果缓存未失效,则返回http码304继续使用缓存;如果失效,则返回新数据和缓存规则,浏览器响应数据后,在把规则存入到缓存数据库中;
协商缓存在请求数上和没有缓存策略是一样的,但是它的性能优化在于,他返回仅仅是一个状态码,没有实际文件内容,所以在响应体的体积上缩小了很多,相当于减少了响应这个过程的时间,通过缩小响应体积而缩短传输时间来实现性能优化;
如何设置?
按优先级排序是if-modifi-since&last-modified < Etag & If-None-Match
1.if-modifi-since&last-modified:
判断响应头中的Last-Modified,服务端告知客户端,最后一次资源被修改的时间; Last-Modified: Tue, 11 Nov 2023 11:11:11 GMT 浏览器将这个值赋值给请求头中的if-modified-since,当有同样的请求时,服务器会将相应头中的Last-Modified和请求头中的Last-Modified进行对比,值相等,返回304码,反之,返回新数据和200等; 缺点:最小单位是秒,如果请求很近,无法对比;如果文件是服务器动态生产,那每次请求都动态生产一次,更新时间也就是生产时间,起不到缓存的作用。2.Etag&if-none-match:
为了弥补if-modifi-since&last-modified的缺点; 判断响应头中的Etag的值,如果服务器中文件内容有变化那么Etag值也会变,通过值来进行对比。那么整体请求的流程就是:
- 当我们输入一个url请求时,浏览器请求调用service worker中的fetch()事件响应;
- 去memory cache中查看,没有命中继续;
- 去disk cache中查看,细分为: 1.强缓存;2.协同缓存
- 发送网络请求,获取响应;
- 把响应内容存入disk cache中,根据HTTP头的规则;
- 把响应内容的引用存入memory cache中,和http头无关;
- 如果server worker脚本调用了catch.put(),就把响应内容存入Service Worker的cache stroage中。
浏览器行为如何触发缓存策略:
- 打开浏览器,地址栏输入网址:从disk cache开始;
- 普通刷新:没有关闭tab页的情况下,从memory cache开始;
- 强制刷新:浏览器不使用缓存,因为强制刷新时请求头都有cache-control:no-cache,pagema:no-cache;服务器返回200和最新内容。