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

112 阅读6分钟

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

什么是HTTP缓存?

HTTP缓存是一种利用HTTP协议中的一些字段和规则,来在客户端或者代理服务器中存储和重用HTTP响应的技术。HTTP缓存可以提高网页或者应用程序的性能和用户体验,减少网络流量和服务器负载。

HTTP缓存有哪些类型?

HTTP缓存可以分为两种类型:强缓存和协商缓存。

  • 强缓存:强缓存是指客户端在发送请求之前,先根据本地缓存中的一些信息,来判断是否可以直接使用缓存中的响应,而不需要向服务器发送请求。强缓存可以通过两种方式来实现:Expires头和Cache-Control头。

    • Expires头:Expires头是一个表示响应过期时间的字段,它的值是一个绝对的时间点,例如Expires: Wed, 21 Oct 2023 07:28:00 GMT。客户端在发送请求之前,会检查本地缓存中是否有对应的响应,并且比较当前时间和Expires头的值,如果当前时间小于Expires头的值,说明响应还没有过期,可以直接使用缓存中的响应;如果当前时间大于或等于Expires头的值,说明响应已经过期,需要向服务器发送请求。Expires头的一个缺点是它依赖于客户端和服务器之间的时间同步,如果有时差或者误差,可能会导致缓存失效或者错误。
    • Cache-Control头:Cache-Control头是一个表示响应缓存控制策略的字段,它的值是一个或多个指令(directives),例如Cache-Control: max-age=3600, public, no-transform。客户端在发送请求之前,会检查本地缓存中是否有对应的响应,并且根据Cache-Control头中的指令来判断是否可以使用缓存中的响应。其中最重要的指令是max-age,它表示响应可以被缓存多长时间(单位是秒),例如max-age=3600表示响应可以被缓存3600秒。客户端会记录响应到达的时间,并且计算出过期时间,如果当前时间小于过期时间,说明响应还没有过期,可以直接使用缓存中的响应;如果当前时间大于或等于过期时间,说明响应已经过期,需要向服务器发送请求。Cache-Control头相比于Expires头,有更多的指令和更精确的控制能力,而且不依赖于客户端和服务器之间的时间同步。因此,在HTTP/1.1中,推荐使用Cache-Control头来实现强缓存。
  • 协商缓存:协商缓存是指客户端在发送请求时,先向服务器询问是否可以使用本地缓存中的响应,而不是直接使用。协商缓存可以通过两种方式来实现:最后修改时间(Last-Modified)和实体标签(ETag)。

  • 最后修改时间:最后修改时间是指服务器在返回响应时,通过一个名为Last-Modified的字段来表示资源最后一次被修改的时间,例如Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT。客户端在发送请求时,会通过一个名为If-Modified-Since的字段来携带本地缓存中的响应的最后修改时间,例如If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT。服务器在接收到请求时,会比较请求中的最后修改时间和资源的最后修改时间,如果两者相等,说明资源没有被修改,可以使用缓存中的响应;

HTTP缓存策略是一种利用HTTP协议中的一些字段和规则,来在客户端或者代理服务器中存储和重用HTTP响应的技术。HTTP缓存策略可以分为强缓存和协商缓存,分别使用不同的方式来判断是否可以使用缓存中的响应。HTTP缓存策略可以根据不同的场景和需求,来选择合适的缓存控制策略,以提高网页或者应用程序的性能和用户体验,减少网络流量和服务器负载。

在上一节中,我们已经介绍了HTTP缓存策略的两种类型:强缓存和协商缓存,以及它们的实现方式和优缺点。在这一节中,我们将通过一个具体的例子,来分析HTTP缓存策略在浏览器中的应用场景。

我们可以使用Chrome浏览器来访问一个网站,并使用开发者工具(DevTools)来查看网络请求和响应中的相关字段。以下是一个访问GitHub首页(github.com/)时的网络请求和响应的…

![network2]

从截图中我们可以看到:

  • 对于GitHub首页本身(github.com/)的请求和响应,服务器…: no-cache头和一个ETag: W/"a9c8a7d7d7d7d7d7"`头,表示这个响应不能被强缓存,但是可以被协商缓存,并且使用弱实体标签(weak ETag)来判断资源是否被修改。这是因为GitHub首页可能包含一些动态变化或者敏感的内容,不适合使用强缓存,但是可以使用协商缓存来节省一些带宽。

  • 对于GitHub首页上的一些静态资源(如图片、样式表、脚本等)的请求和响应,服务器返回了一个Cache-Control: max-age=31536000, public, immutable头和一个ETag: "a9c8a7d7d7d7d7d7"头,表示这些响应可以被缓存31536000秒(约1年),并且可以被任何中间代理缓存,并且不会被修改,并且使用强实体标签(strong ETag)来判断资源是否被修改。这是因为这些静态资源可能不会经常变化或者有版本控制,适合使用强缓存和协商缓存。其中,immutable指令是一个扩展的指令,用来表示资源在缓存期间不会被修改,可以避免一些不必要的协商缓存请求。

  • 对于GitHub首页上的一些动态资源(如API、AJAX等)的请求和响应,服务器返回了一个Cache-Control: no-cache, no-store, must-revalidate头和一个ETag: W/"a9c8a7d7d7d7d7d7"头,表示这些响应不能被缓存,每次都需要向服务器发送请求,并且使用弱实体标签来判断资源是否被修改。这是因为这些动态资源可能会根据用户的行为或者偏好来变化,不适合使用缓存。

通过这个例子,我们可以看到HTTP缓存策略在浏览器中的具体应用场景,以及不同类型的资源如何使用不同的缓存控制策略。我们可以使用开发者工具来查看网络请求和响应中的相关字段,以及缓存命中或者未命中的状态,从而分析和优化我们的网页或者应用程序的性能和用户体验。😊