八股文不用背-浏览器缓存

128 阅读3分钟

背景

我用浏览器访问一个网站,第一次访问时,下载了一个图片,该图片是长久使用的。
那我第二次访问该网站时,该图片再下载的话,不仅浪费了流量,还增加了资源加载的时间。
如果第一次获取该图片时,就能缓存下来,之后访问就不需要下载啦,用户体验会好很多(首屏渲染时间减少了)。

为什么要使用浏览器缓存

  1. 减少请求
  2. 减少服务器压力
  3. 减少加载时间

浏览器缓存有哪些

强缓存

浏览器直接从缓存中读取强缓存的资源,不发送请求,比如某网站需要下载jquery-1.0.0,那这个资源几乎是不需要更新的,直接强缓存,下次获取时,直接从缓存里面拿。

  • Expires:代表资源的失效时间,当服务器时间和浏览器时间偏差⼤会出现问题
  • Cache-Control:max-age=3600 代表着资源有效时间为3600秒
  • no-cache:是否不使⽤本地存储,使⽤协商存储
  • no-store:是否禁⽌浏览器缓存数据
  • public:是否可以被所有⽤户缓存,包括终端⽤户和CDN中间服务器
  • private:只能被终端⽤户浏览器缓存,不允许CDN服务器缓存

强缓存是通过http返回头的中Expires或者Cache-Control两个字段来控制的,⽤来标记资源的缓存时间 Chache-Control与Expires可以在服务器端配置里同时启⽤,⽽Cache-Control级别更⾼

协商缓存

协商缓存就是服务器确定缓存资源是否可⽤,比如b站的用户头像,用户A第一次登陆B站便在本地缓存了自己的头像图片资源,这个资源只有用户自己更新了头像才需要去更新缓存,那么用户每次访问B站时,都询问下后端是否继续使用本地缓存即可,这就是协商缓存,主要通过以下两对标识来决定。

Last-Modify/If-Modify-Since

比如:服务器设定资源A有效期只有一天,那么第二天再获取该资源就得后端返回,那我们就可以给资源设置一个时间字段来判断该资源是否过期了。

浏览器第⼀次请求⼀个资源的时候,服务器返回的header会加上Last-Modify,Last-Modify是⼀个时间,标志着该资源最后的修改⽇期。
当浏览器再次请求该资源的时候,request的请求头会包含If-Modify-Since字段,值为Last-Modify,服务器若想让浏览器继续使用这个缓存,则返回304,否则返回新资源。

ETag/If-None-Match

比如:用户A第一次登陆b站获取的头像资源的ETag是1,此刻服务器内的该头像资源的ETag也是1,若第二天用户A修改了自己的头像,那么服务器内的该头像资源的ETag就是2,但用户A自己浏览器里的该头像资源的ETag是1,就对不上了,那么服务器就得返回新的资源给浏览器。

与Last-Modify/If-Modify-Since不同的是,ETag返回⼀个校验码,保证每个资源是唯⼀的,资源的变化都 会导致ETag变化,服务器通过返回In-None-Match是否为true来决定是否返回新资源

同时,ETag也能处理以下问题:

  • ⼀些⽂件周期性改变,但是内容不改变,服务器会认为要修改,但是我们不想他改变;
  • 某些⽂件修改频繁,Last-Modify/If-Modify-Since是以秒为级别的,但修改频率过⾼,我们不期望这样,便⼀般优先验证ETag

看到这里的看官,麻烦点个赞赞吧