JS中的强缓存和协商缓存
文章类型:Javascript
发布者:hp
发布时间:2022-09-02
浏览器访问网站,会加载html,css,jsimg....,如果每次都需要重新加载,对服务器压力,用户体验不好,这个时候我们都需要进行缓存。
强制缓存优先于协商缓存,若强制缓存(Expires 和Cache-Control)生效则直接使用缓存,否则则使用协商缓存(Last-Modified/If-Modified-Since/Etag/If-None-Match)
协商缓存则又根据服务器决定,若失败,则代表请求缓存失败,返回200,重新返回缓存资源和缓存标识,再存入浏览器中,生效则返回304,继续使用缓存
浏览器缓存执行图解
一:强制缓存
通过Expires和Cache-Control两个字段进行控制,都表示资源缓存的有效时间,
1:Expires:值是一个GMT格式时间字符串,比如:Expires:Mon,10 Oct 2022 20:50:50 GMT,在这个时间之前都认为命中缓存,
他是一个绝对时间,如果服务器和客户端时间相差很大,就会导致缓存混乱。
2:Cache-Control:常用max-age值来进行判断,单位值是秒,是一个相对时间,
比如max-age:3600表示资源有效期是3600秒,表示当前资源在Date~Date+3600都是有效的。当然也会出现服务器时间跟本地系统时间不同的情况,
no-cache 不使用本地缓存。需要使用协商缓存。
no-store直接禁止浏览器缓存数据,每次请求资源都会向服务器要完整的资源。
public 可以被所有用户缓存。
private 只能被终端用户的浏览器缓存。
如果Cache-Control和Expires同时存在,Cache-Control优先级更高,Cache-Control > expires > Etag > Last-Modified
图解
二:协商缓存
主要是采用两种方式进行操作,来绝对是否命中缓存
1:Last-Modified/If-Modified-Since:都是GMT格式的时间字符串,Last-Modified表示最后文件修改时间,
下一次请求时头部带上If-Modified-Since:Last-Modified的值,服务器根据最后修改时间进行判断是否有变化,没变化则返回304 ,
如果有变化 则返回新的资源内容,同时在response header返回新的Last-Modified.
2:Etag/If-None-Match:值是由服务器生成的资源id唯一字符串,
只要资源有变化值就会改变,服务器根据文件本身算出一个哈希值通过Etag返回给浏览器,
下一次请求时If-None-Match:Etag值,服务器通过比较判断是否改变,没改变返回304,有改变则重新返回Etag
推荐使用Etag,主要是Lat-Modified精确度只能到秒级、其次是某些服务器不能精确读取到最后修改时间、文件周期性的改变,内容相同也会被重新触发
图解
Last-Modified/If-Modified-Since图解
Etag/If-None-Match图解
缓存的优缺点:
优点:
1:减少重复数据请求,避免网络再次加载资源,节省流量。
2:减轻服务器压力,提升完整性能.
3:加快客户端加载网页速度,提升用户体验
缺点:
1:缓存了静态文件,如果没过期,则需要强制清除本地缓存,才能看到最新的发布版本
解决方案
1:每次手动添加版本号或者动态加上时间戳
2:每次对应静态文件里有内容改动的时候,自动加一段 hash 到静态文件名里