浏览器缓存个人笔记

108 阅读7分钟

浏览器缓存

首先我们要知道,为了浏览器性能,缓存策略的原则是能使用缓存要尽量使用缓存以更快加载页面

缓存位置

  1. Service Worker Service Worker是运行在浏览器背后的独立线程,传输协议必须为HTTPS,因为涉及请求拦截,要使用HTTPS协议保障安全,ServiceWorker的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件,如何读取缓存,并且缓存是持续性的,实现缓存分为三个步骤,首先注册Service Worker,然后监听到install事件以后就可以缓存需要的文件,那么下次用户访问就可以通过拦截请求的方式查询是否存在缓存,若存在缓存直接读取缓存文件,否则去请求数据,当ServiceWorker没有命中缓存时,通过fetch函数根据优先级查找数据 但是不管我们是从memory cache还是从网络请求中获取数据,浏览器都会显示我们是从service cache中获取的

  2. Memory Cache 内存中的缓存,主要内容是当前页面中已经抓取的资源,例如页面上已经下载的样式,脚本,图片等 读取内存中的数据肯定比磁盘快,但持续性短,会随着进程的释放而释放,一旦关闭TAB页面(类似一个网站的主页),内存的缓存就被释放了 内存容量非常小, 内存缓存中的一块重要的缓存资源是preloader相关指令下载的资源,preloader是一种页面优化的常见手段之一,一边解析JS/CSS文件,一边网络请求下一个资源。preloader可以实现资源的提前加载,字体的提前加载,实现一些需要在某个时刻运行的函数的加载 内存缓存缓存资源时并不关心HTP的缓存头的Cache-Control的值,同时资源的匹配并非仅仅对URL做匹配,可能对Content-Type,CORS等其他特征进行校验

  3. Disk Cache 硬盘缓存读取速度慢,时效性强,所有浏览器缓存中,Disk Cache的覆盖面基本是最大的,会根据HTTP Header中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求,在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次请求数据,绝大部分的缓存来自Disk Cache

大文件一般不会存储在内存中,反之优先 对当前系统内存使用率高的,优先存储进硬盘

  1. Push Cache 推送缓存时HTTP/2的内容,当以上三种缓存东都没有命中时,它才会被使用,只在Session(session存储于服务器,是维护会话状态的key,而window对象中的sessionStorage中存储着后台的session)中存在,一旦会话结束就被释放,缓存时间也很短暂

所有资源都能被推送,并且可以被缓存,但是Edge和Safari浏览器支持较差 可以推送no-cache和no-store的资源 一旦连接被关闭,Push Cache就被释放 浏览器可以拒绝接受已经存在的资源推送 给其他域名推送资源 Push Cache 中的缓存只能被使用一次

以上四种都没有命中的话,就要通过发起请求来获取资源

浏览器缓存策略

缓存过程分析

浏览器与服务器的通信方式为应答模式 浏览器发起HTTP请求-服务器响应该请求 浏览器对于缓存的处理是根据第一次请求资源时返回的响应头进行处理的 浏览器每次发起请求,都会现在浏览器缓存中查找该请求的结果以及缓存标识 浏览器每次拿到的请求结果都会将该结果和缓存标识存入浏览器缓存中 label

强缓存

不会向服务器发送请求,直接从缓存中读取资源,在chrome的network可以看到请求返回200的状态码,并且size显示from disk cache或from memory cache,强缓存通过设置两种Header实现,Expires和Cache-Control

  1. Expires 缓存过期时间,用来指定资源到期的时间,Expires = max-age + 请求时间, Expires是HTTP/1的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效

  2. cache-control 在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,比如当Cache-Control:max-age=300时,代表在这个请求正确返回时间(浏览器会记录下来)的5分钟内再次加载资源,就会命中强缓存

cache-control的优先级高于expires

label

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,有服务器根据缓存标识决定是否使用缓存的过程

协商缓存会有两种状态,一种是生效,资源无更新,直接从缓存获取资源,另一种是失效,资源更新,重新返回请求结果并将该请求结果和缓存标识存储在缓存中

协商缓存生效,返回304和Not Modified label

  1. Last-Modified和If-Modified-Since 浏览器第一次访问资源时,服务器返回资源时,检测有Last-Modified这个header,添加If-Modified-Since这个header,值是Last-Modified的值,服务器再次接受到这个资源请求,会根据If-Modified-Since中的值和服务器中的这个资源的最后修改时间对比,如果没有变化,会返回304和空的响应体,如果值小于最后修改时间,说明文件有更新,返回新的资源文件和200

按秒计时,无法处理单位更小的时间 本地打开缓存文件会导致Last-Modified修改,不能命中缓存导致发送相同的资源

  1. ETag和If-None-Match Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,ETag就会重新生成,浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头的If-None-Match中,服务器会判断客户端If-None-Match和自己服务器上的资源的ETag是否一致,如果匹配不上,就直接以GET 200闭包形式将新的资源发给客户端,如果ETag一致,返回304让客户端返回本地缓存即可

比较:Last-Modified的性能更好,因为ETag要计算一个hash值 精确度上ETag优于Last-Modified 优先级上,服务器优先考虑ETag

  1. 缓存机制 强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match)由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。 label

如果浏览器什么缓存策略都没设置,会采用响应头的Date减去Last-Modified的值作为缓存时间

频繁变化的资源使用cache-control:no-cache使浏览器每次都请求服务器,配合ETag和Last-Modified来验证

不常变化的资源使用 cache-control: max-age = 31536000 设置一个一年的过期时间,为了处理更新,需要在文件名或路径添加hash,版本号等动态字符,让之前的强制缓存不再使用

label

PS:本人菜鸟,如有错误,敬请原谅并欢迎提出