浏览器缓存策略应用

什么是强缓存

  • 强制缓存:设置缓存机制后,前端第一次请求到资源会把资源缓存到客户端,如果下次请求时资源没有过期,那么直接调用本地缓存的资源,如果过期则重新发送请求。
  • 强制缓存由服务端开启,利用http头中的ExpiresCache-Control两个字段来控制
  • 注意点:
    1. 强制缓存不用和服务端交互;
    2. 客户端设置请求头Cache-Control,只有为:no-storeno-cachemax-age=0才会生效(也就是客户端不想走强制缓存的时候生效。no-cache意思是不走强缓存,走协商缓存;no-store意思是不使用缓存),
    3. 强缓存返回状态码为200;
    4. post请求不能设置缓存,只有get请求有效。

演示说明

  • Expires:表示响应头里面的过期时间,如果超过改时间,浏览器再次加载资源时(例如刷新页面,就会重新请求该资源文件,否则不会重新请求,会使用浏览器存储起来的缓存)
    图片1.png
图片2.png
  • 从这里可以看出,请求该文件的时间是 1 该文件过期的缓存时间是2 (即1分钟以内请求该资源浏览器将使用缓存,否则重新请求)

  • 而从图二更能清晰表面,第一次请求的时候使用的是请求的资源第二次请求的时候使用的是缓存资源

什么是协商缓存

  • 协商缓存:第一次请求资源时,服务器会返回资源以及资源标识,当下次请求时,会对比资源标识,如果一致,则只返回状态码304,不用返回资源,如果不一致,则会返回资源和新的资源标识。
  • 协商缓存主要依赖的响应头包括last-modifiedETag
  • 注意点:
    1. 协商缓存需要和服务器交互;
    2. 请求资源命中协商缓存后,返回的状态码为 304
    3. last-modified 记录资源最后修改的时间。启用后, 请求资源之后的响应头会增加一个last-modified字段

演示说明:

image.png
image.png
image.png
  • 从这里可以看出返回状态码 304 表示当前为协商缓存数据。
  • 图二 Etag 表示当前文件的标识,服务器上存储着文件的Etag字段,可以在与每次客户端请求头里面的If-no-match的字段进行比较。如果相等,则表示未修改,响应304;反之,则表示已修改,响应200状态码,返回数据。
  • Last-Modified 则表示该资源文件的最后一次修改的时间,它会与每次客户端请求头里面的If-Modified-Since字段进行对比,如果相等,则表示未修改,响应304状态码,告诉客户端可继续使用缓存;反之,则表示修改了,响应200状态码,返回 新的资源数据

使用什么方案及如何配置?

  1. 方案:

    • 前端 协商缓存,后端 强缓存
  2. 为什么?

    • 因为进行JS CSS 图片资源这种一般打包后都不会随便修改,所以直接使用强缓存即可。

    • 因为 HTML 文件引入的CSS js资源存在修改的情况,所以使用协商缓存。(场景需求:需将线上 P标签 的字体颜色变为 红色,经过打包后重新生成新的HTML文件)

    • 如下所示,引入的css js文件经打包后名字(也可以手动重命名)重新发生了改变,html重新上线后会请求新的css js文件,达到修改的效果。

    • 注意点:推荐采用 非覆盖式 部署,避免直接替换后某些用户无法访问到旧的资源文件,出现报错的情况,即保留除HTML文件外的其它全部文件,将新的资源文件直接上传,同时 HTML 文件覆盖后,进行必要留存文件命名,方便需要时进行版本回滚,例如 HTML-v1.1

      //原HTML文件
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>node demo</title>
        <link rel="stylesheet" href="/index-s3ds45d.css">
      </head>
      
      <body>
        <p>hello world</p>
        <script src="/index-lsdsa876sd.js"></script>
      </body>
      
      //新HTML文件
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>node demo</title>
        <link rel="stylesheet" href="/index-fsdsd09d1.css">
      </head>
      
      <body>
        <p>hello world</p>
        <script src="/index-gses456h.js"></script>
      </body>
      
  3. 如何配置?

    • 前端HTML文件配置

      //禁用缓存如下:
      <meta http-equiv="pragma" content="no-cache">
      // 仅有IE浏览器才识别的标签,不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求
      <meta http-equiv="cache-control" content="no-cache">
      // 其他主流浏览器识别的标签
      <meta http-equiv="expires" content="0">
      // 仅有IE浏览器才识别的标签,该方式仅仅作为知会IE缓存时间的标记,你并不能在请求或响应报文中找到Expires字段
      
    • 后端可以通过 nginx 进行配置(这里为了演示,所以设置缓存周期为60秒)

image.png

HTML字段补充说明

expires

可以用于设定网页的到期时间。一旦网页过期,必须到服务器上重新传输。

cache-control

指定请求和响应遵循的缓存机制。共有以下几种用法:

  • no-cache: 先发送请求,与服务器确认该资源是否被更改,如果未被更改,则使用缓存。
  • no-store: 不允许缓存,每次都要去服务器上,下载完整的响应。(安全措施)
  • public : 缓存所有响应,但并非必须。因为max-age也可以做到相同效果
  • private : 只为单个用户缓存,因此不允许任何中继进行缓存。(比如说CDN就不允许缓存private的响应)
  • max-age : 表示当前请求开始,该响应在多久内能被缓存和重用,而不去服务器重新请求。例如:max-age=60表示响应可以再缓存和重用 60 秒。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容