浏览器缓存机制

71 阅读3分钟

在一个 web 应用的数据传递流程中,有很多比较费时的步骤,如客户端给服务器发送请求、 服务器请求数据库数据、涉及大量计算的时候,都需要对应的缓存机制去优化性能,有数据库缓存、应用层缓存、代理服务器缓存、CDN 缓存、浏览器缓存,前端主要关注的是浏览器缓存。

整个浏览器的缓存过程如下:

image.png

浏览器缓存机制共有两个重要概念:

  • 缓存的存储位置
  • 缓存的类型

按照缓存位置分类

缓存位置有 4 个,浏览器会按照优先级依次匹配缓存内容:

  • Service Worker:是运行在浏览器背后的独立线程,必须是 HTTPS 协议才可用
  • Memory Cache:内存中的缓存
  • Disk Cache:硬盘中的缓存
  • Push Cache:推送缓存,是 HTTPS/2 中新增的内容

按照缓存类型分类

分为强制缓存协商缓存,都是属于 Disk Cache 里的一种。

强制缓存

强缓是当客户端请求后,会先访问缓存数据库,如果不存在再去请求服务器,等响应后再写入缓存数据库。

优化点:强缓直接减少了请求数,是提升最大的浏览器缓存策略。

在响应头中添加 Expires 或 Cache-control 可开启强缓:

  • Expires:用的是绝对时间,且写法复杂,属于 HTTP 1.0
  • Cache-control:用的相对时间,常用,属于 HTTP 1.1
Cache-control: max-age=2592000 // 表示资源缓存的最大有效时间
Cache-control: no-store // 表示所有内容都不走缓存,包括强制缓存和协商缓存

协商缓存

当强缓失效时,如超过有效时间,这时候就需要使用协缓,由服务器决定缓存是否失效。
流程上,浏览器会先请求缓存数据库,返回一个缓存标识,用这个标识和服务器通信:

  • 服务器判定缓存未失效,返回 304 状态码,客户端继续使用缓存。

image.png

  • 服务器判定缓存失效,返回新数据和缓存规则,客户端获取数据并把规则写入缓存数据库。

image.png

优化点:协商缓存在请求数量上和无缓存一致的,但如果是 304 的话,返回的仅仅是个状态码,没有实际文件内容,因此大大节省了响应体的体积。

这个缓存标识一般是 Etag,存储的是文件的特殊标识(一般是个 Hash 值),服务器存储着文件的 Etag 字段,通过对比客户端传来的和服务器上该资源的 Etag 是否一致,来判断该资源是否被修改过。

缓存读取规则

当浏览器请求资源时,查看 Disk Cache 的流程:

image.png

浏览器行为

用户对浏览器的不同操作,会触发不同的缓存读取策略:

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