浏览器中的缓存策略是什么?

111 阅读4分钟

针对上一篇提到的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值也会变,通过值来进行对比。
    
    那么整体请求的流程就是:
    1. 当我们输入一个url请求时,浏览器请求调用service worker中的fetch()事件响应;
    2. 去memory cache中查看,没有命中继续;
    3. 去disk cache中查看,细分为: 1.强缓存;2.协同缓存
    4. 发送网络请求,获取响应;
    5. 把响应内容存入disk cache中,根据HTTP头的规则;
    6. 把响应内容的引用存入memory cache中,和http头无关;
    7. 如果server worker脚本调用了catch.put(),就把响应内容存入Service Worker的cache stroage中。
    浏览器行为如何触发缓存策略:
    1. 打开浏览器,地址栏输入网址:从disk cache开始;
    2. 普通刷新:没有关闭tab页的情况下,从memory cache开始;
    3. 强制刷新:浏览器不使用缓存,因为强制刷新时请求头都有cache-control:no-cache,pagema:no-cache;服务器返回200和最新内容。