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 到静态文件名里