Web缓存

参考文档

深入理解浏览器的缓存机制 https://www.jianshu.com/p/54cc04190252

一文读懂前端缓存 https://mp.weixin.qq.com/s/cUqkG3NETmJbglDXfSf0tg

 

缓存的分类

  • 按存储位置分
    • memory cache:
      • 存储在内存
      • 关闭tab时清空
      • 缓存内容太多且没关闭tab时清掉最早的
      • 不受http协议头控制
    • disk cache:
      • 存储在硬盘
      • 允许相同资源在跨会话、跨站点情况下使用
      • 容量增长后浏览器按照自己的算法计算删除最老的资源
      • 受强制缓存策略影响
  • 按失效策略分
    • 强制缓存
      • 先查看有无缓存,没有的话才请求服务
      • 直接减少请求次数
      • 策略直接影响disk cache
    • 协商缓存
      • 强制缓存失效时,使用协商缓存
      • 请求服务器,询问缓存是否仍然可用,可用则继续使用,不可用则同时返回新的资源

请求头设置规则

  • 强制缓存
    • Expires:缓存到期时间绝对值,具体日期时间点
    • Cache-control:资源最大有效时间,在该时间段内客户端不向服务端发请求
      • max-age:即最大有效时间,单位秒
      • must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
      • no-cache:只避免强制缓存,使用协商缓存,内存缓存有效。也就是说,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载。
      • no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括内存、强制缓存和协商缓存。
      • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
      • private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。
  • 协商缓存
    • 响应头Last-Modified & 请求头If-Modified-Since
      • 服务器通过 Last-Modified 字段告知客户端,资源最后一次被修改的时间
      • 浏览器将这个值和资源内容一起存在缓存中
      • 下一次请求相同资源时时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。在请求头中将上次的 Last-Modified 的值写入到请求头的 If-Modified-Since 字段
      • 服务器会将 If-Modified-Since 的值与 Last-Modified 字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据
    • 响应头Etag & 请求头If-None-Match
      • Etag 存储的是文件的特殊标识(一般都是 hash 生成的),服务器存储着文件的 Etag 字段。
      • 流程与Last-Modified类似,只是在服务端对比的是文件内容(hash)
  • 缓存优先级
    • memory cache > disk cache
    • 强制缓存(Cache-control > Expires) > 协商缓存(Etag > Last-Modified) 

浏览器处理流程

  1. 查看memory cache,有则使用memory cache
  2. 查看disk cache
    1. 强制缓存未过期:使用强制缓存,状态码200
    2. 强制缓存已过期:服务端确认缓存是否可用,根据结果判断使用缓存(状态码:304)还是新资源(状态码:200)
  3. 发送请求,等待响应
  4. 将响应资源存入disk cache(http协议头允许的情况下)
  5. 将响应资源存入memory cache(除no-store外,忽略其他http协议头)

如果什么缓存策略都没设置,那么浏览器会怎么处理?

对于这种情况,浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。

所谓用户行为对浏览器缓存的影响,指的就是用户在浏览器如何操作时,会触发怎样的缓存策略。主要有 3 种:

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

缓存设置方式

  1. HTML Meta标签控制缓存(非HTTP协议定义)
    • 优点:使用上很简单
    • 缺点:但只有部分浏览器可以支持(兼容性);所有缓存代理服务器都不支持,因为代理不解析HTML内容本身
  2. HTTP头信息控制缓存(响应头)
    • 使用nginx配置响应头,将缓存策略传递给浏览器及相关缓存代理服务器

缓存策略

对于已有react前端项目现状

  • js、css文件
    • 每次构建内容改变会修改名称,可以使用强制缓存,修改文件名后发送新请求
  • 图片
    • 目前项目中图片比较固定,修改小,没有特殊需求可以先使用js、css文件相同策略,变动时修改文件名称
  • html
    • 所有js、css文件都在html中引用,如果html使用原有文件会出现全套使用老版本的情况,所以html采用不缓存策略(no-store)
    • html文件较小,只有js、css等文件的引用,请求资源大小在1-2kb左右,不会产生太多消耗

 实例

html文件服务端返回不做缓存策略设置时,以下几种状况下的请求头

 ctrl+F5强制刷新

F5刷新

 

 首次请求

原文地址:https://www.cnblogs.com/zs-note/p/13043185.html