一、浏览器缓存简介  

  • 1、浏览器通过缓存服务器返回的资源(针对静态资源和get请求),减少传输压力,提高访问速度。 
  • 2、那么缓存的目标应该是:资源可以被缓存 + 保证不使用过期的资源 + 服务器资源部分更新的时候不能导致新旧文件内容不一致。所以可以结合实际情况,设置适当的缓存策略。
  • 3、浏览器无缓存的过程:
    浏览器请求 ---> 无缓存 ---> 请求WEB服务器 ---> 请求响应 ---> 呈现
  • 4、浏览器有缓存的过程:
    浏览器请求 ---> 有缓存 ---> 校验过期(无需发请求) ---> 是否有更新(需要发请求,结合Etag或Last-Modified验证更新) ---> 呈现

    二、常见缓存策略

    http本身是个协议,缓存是浏览器实现的。可以通过设置或读取HTTP头来实现对应的缓存机制(强缓存和协商缓存)。

  • 1、 强缓存策略(可以强制缓存并定义足够长的过期时间让资源在本地长期驻留,但是不能及时更新):Cache-Control和Expire

    • Cache-Control:max-age 的优先级要比Expires高。若命中,则不向服务器发请求。
    • Expires有弊端:是绝对时间,依赖客户端时间,可能和服务端时间不一致。
  • 2、协商缓存(用于检测新鲜度,协商缓存能够保证及时更新,但是会频繁地去服务器验证,浪费性能):Etag(和If-None-Match一对) 和 Last-Modified(和If-Modified-Since一对);每次都要向服务器get请求验证。

    • Last-Modified有缺陷:  

      • (1)只是编辑了文件,但是文件内容没有变化,Last-Modified也会改变
      • (2)Last-Modified只能精确到s,如果文件操作在ms级操作,则精确不到
    • Etag根据文件内容生成hash(通常最终的 ETag 将由实体的长度和哈希值两部分组成。),更精确,也有缺陷:

      • (1)服务器计算etag需要额外的性能开销
      • (2)分强验证(每个字节都相同)和弱验证(部分字节相同),要根据具体的业务场景合理选择。
  • 3、缓存优先级:

    • Cache-Control(强) > Expires (强)> Etag / If-None-Match > Last-Modified / If-Modified-Since

      三、实践

  • index.html入口资源:

    • 要保证及时更新,可设置协商缓存,cache-control: no-cache
  • cdn上的资源

    • 如vue,不经常变动,路径中有版本号,可以设置很长的时间,如cache-control: max-age=31536000(一年)
    • cdn上的配置文件,有可能会很快变化,有可能也不快,可设置cache-control: max-age=86400(一天)(可用cdn的主动刷新机制)
  • 图片,视频等资源

    • 不经常更改且占用缓存空间大,可设置强缓存且过期时间不宜太长,如cache-control: max-age=86400(一天)
  • 项目的业务CSS和JS等资源

    • 内容可能不定期修改,可结合webpack生成带hash的文件,如style.51af3464.css。如果文件内容变了,打包后的hash也会变,url就会变,浏览器会重新请求,所以过期时间可以很长。如cache-control: max-age=31536000(一年)
    • JS脚本文件:如果js资源中包含私人信息,则不能让中间代理缓存,则要为cache-control添加private

      四、示例

      1、无缓存no-cache
      图片

五、用户行为对浏览器缓存的影响

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

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

雨花石
410 声望19 粉丝

人生没有彩排,每天都是直播