HTTP缓存的场景实践 | 青训营

707 阅读6分钟

本文是一篇关于HTTP缓存的基础知识以及场景实践,对于HTTP中涉及的请求中的缓存策略展开具体分析。

什么是 HTTP Cache

众所周知通过网络获取资源缓慢且耗时,需要三次握手等协议与远程服务器建立通信,对于较大较多的数据需要多次往返通信大大增加了时间开销,并且当今流量依旧没有理想的快速与便宜。对于开发者来说,长久缓存复用重复不变的资源是性能优化的重要组成部分。

HTTP 缓存机制就是,配置服务器响应头来告诉浏览器是否应该缓存资源、是否强制校验缓存、缓存多长时间;浏览器非首次请求根据响应头是否应该取缓存、缓存过期发送请求头验证缓存是否可用还是重新获取资源的过程。

缓存的分类

根据是否需向服务器发起HTTP请求,将缓存过程划分为两个部分:
强制缓存和协商缓存,强缓优先于协商缓存。

  • 强缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
  • 协商缓存,让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

HTTP缓存都是从第二次请求开始的:

  • 第一次请求资源时,服务器返回资源,并在response header中回传资源的缓存策略;
  • 第二次请求时,浏览器判断这些请求参数,击中强缓存就直接200,否则就把请求参数加到request header头中传给服务器,看是否击中协商缓存,击中则返回304,否则服务器会返回新的资源。这是缓存运作的一个整体流程图:

image.png

强缓存

强缓存的意思很简单,直接从浏览器缓存过的本地进行读取,不会去请求服务器。例如请求一个图片,当缓存后,第二次访问,直接从本地去拿,不会再去请求这个资源,可以节省服务器资源。

Expires:服务端在响应头中设置一个 GMT 格式的到期时间。客户端的本地时间小于响应头的 Expires 时间,那么会从本地进行读取,不会去请求服务器。如果超过了,那么就去请求服务器去获取最新资源。但是就是因为根据本地时间进行判断,本地时间可以随便修改,所以这种缓存机制有漏洞,会与服务端时间有偏差,为了解决这个问题,就出现了下面的 Cache-contorl
Cache-control:他和Expires不一样,Expires是直接设置一个时间戳就行了,而Cache-control可以设置下面这几种属性:

max-age:这个用于设置一个滑动时间,例如设置 max-age=30 表示客户端时间向后滑动30秒,在这30秒内都是强缓存,不会去请求服务器
s-maxage:这个和上面的一样,只不过这个设置的是代理服务器的缓存时间
privte:这个表示缓存只能被客户端的浏览器缓存,不能被代理服务器缓存
public:这个表示缓存既可以被浏览器缓存,也可以被代理服务器缓存
no-store:这个属性表示不缓存,在任何情况下,都是与服务器进行最新的交互
no-cache:这个并非不缓存的意思,这个表示强制进行协商缓存,会在下面描述

协商缓存

场景1

当客户端浏览器第一次请求的时候,分为两种情况:

  • 第一种:服务器端返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires
  • 第二种:Cache-Control的属性设置为no-cache时

场景2

浏览器第二次请求时就会与服务器进行协商,对比浏览器中的缓存资源,是否是最新的。

  • 当缓存和服务端资源的最新版本是一致的,那么就无需再次下载该资源,服务端直接返回重定向304 Not Modified 状态码,
  • 如果服务器发现浏览器中的缓存已经是旧版本了,那么服务器就会把最新资源的完整内容返回给浏览器,状态码就是200
  • 服务端是根据HTTP的另外两组头信息,分别是:Last-Modified/If-Modified-Since 与 ETag/If-None-Match,这两组数据一 一对应,互相结合使用

浏览器缓存的优缺点

优点

  • 使用浏览器客户端缓存能够减少请求的时间,提高用户体检,提高页面响应时间。
  • 在前端优化的手段当中,减少http请求的方式,也是其中一种,有效使用缓存,可以减少服务器的压力,提升网站的性能。

缺点

  • 正如字面意思,缓存,就意味着使用缓存的时候,服务器的资源有可能不是最新版本,这就需要在使用的时候,控制缓存的资源和时间,包括常见的CDN手段。

HTTP场景实践

访问https://juejin.cn/PC站,对静态资源进行分析

image.png

状态码是200?那它一定是经过完整的链路吗?

  • Status Code: 200 (from disk cache)可以知道,该响应是从硬盘缓存中得到的

缓存策略是怎么样的?

  • cache-control -> 是强缓存相关协议头,则说明静态资源设置了强缓存相关的一个策略
  • maxage -> 从秒换算后可以得知是一年的时间
  • access-control-allow-origin: * -> 允许所有域名访问
  • content-type -> image/png文件

总结

本文阐述了HTTP缓存机制其实是提高访问速度和解决信息不同步的一种机制。HTTP缓存机制要点如下:

  1. HTTP缓存机制分为强制缓存协商缓存两类。
  2. Expires的值是一个时间,表示这个时间前缓存都有效,都不需要发起请求。
  3. Cache-Control有很多属性值,常用属性max-age设置了缓存有效的时间长度,单位为,这个时间没到,都不用发起请求。
  4. immutable也是Cache-Control的一个属性,表示这个资源永远不用再请求了,但是他兼容性不好,Cache-Control其他属性可以参考MDN的文档
  5. Cache-Controlmax-age优先级比Expires高。

协商缓存常见技术有ETagLast-Modified

  1. ETag其实就是给资源算一个hash值或者版本号,对应的常用request headerIf-None-Match
  2. Last-Modified其实就是加上资源修改的时间,对应的常用request headerIf-Modified-Since,精度为

ETag每次修改都会改变,而Last-Modified的精度只到,所以ETag更准确,优先级更高,但是需要计算,所以服务端开销更大。

强制缓存协商缓存都存在的情况下,先判断强制缓存是否生效,如果生效,不用发起请求,直接用缓存。如果强制缓存不生效再发起请求判断协商缓存