What

什么是 HTTP 缓存
Web 缓存(或 HTTP 缓存)是用于临时存储(缓存)Web 文档(如 HTML 页面和图像),以减少服务器延迟的一种信息技术。Web 缓存系统会保存下通过这套系统的文档的副本;如果满足某些条件,则可以由缓存满足后续请求。

Why

为什么要做 HTTP 缓存

  • 提高响应速度和性能
  • 节省服务器带宽

How

如何做 HTTP 缓存

一、通过 ETag 验证缓存的响应

  • 服务器使用 ETag HTTP 标头传递验证令牌。
  • 验证令牌可实现高效的资源更新检查:资源未发生变化时不会传送任何数据。

第一次请求:
image.png

第二次请求:
image.png

二、Cache-Control

  • 每个资源都可通过 Cache-Control HTTP 标头定义其缓存策略。
  • Cache-Control 指令控制谁在什么条件下可以缓存响应以及可以缓存多久。

image.png

Cache-Control 包含的属性:

  • no-cache:先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求。
  • no-store:禁止浏览器以及所有中间缓存存储任何版本的返回响应。
  • public:表示可被缓存、也可以不缓存,通常情况下并不是必须的,max-age 已经表明是否能被缓存。
  • private:这些响应通常只为单个用户缓存,因此不允许任何中间缓存对其进行缓存,例如:个人数据。
  • max-age:指定从请求的时间开始,允许提取的响应被重用的最长时间,单位:秒。

参数解读示范 👇

max-age=86400 浏览器以及任何中间缓存均可将响应缓存长达 1 天
private, max-age=600 客户端的浏览器只能将响应缓存最长 10 分钟
no-store 不允许缓存响应,每次请求都必须完整获取

三、最佳策略

image.png

四、如何更新、停用缓存

  • 在资源“过期”之前,将一直使用本地缓存的响应。
  • 通过在网址中嵌入文件内容指纹(文件名 hash 值),强制客户端更新到新版本的响应。
  • 为获得最佳性能,每个应用都需要定义自己的缓存层次结构。

image.png

我们来分析上面这个例子:

  • HTML 被标记为 no-cache,每次请求会验证文档是否变化(协商),如果变化了,则获取最新的。
  • 允许浏览器和中间缓存(例如 CDN)缓存 CSS,并将 CSS 设置为 1 年后到期。
  • JavaScript 设置为 1 年后到期,但标记为 private,它包含的某些用户私人数据是 CDN 不应缓存的。
  • 图像缓存时不包含版本或唯一指纹,并设置为 1 天后到期。

技巧 组合使用 ETag、Cache-Control 和唯一网址来实现一举多得:较长的过期时间、控制可以缓存响应的位置以及随需更新。

五、Check List

在制定缓存策略时,需要牢记下面这些技巧和方法:

  • 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次提取和存储这些内容。
  • 服务器提供验证令牌 (ETag):有了验证令牌,当服务器上的资源未发生变化时,就不需要传送相同的字节。
  • 确定中间缓存可以缓存哪些资源:对所有用户的响应完全相同的资源非常适合由 CDN 和中间缓存进行缓存。
  • 为每个资源确定最佳缓存周期:不同的资源可能有不同的更新要求。 为每个资源审核并确定合适的 max-age。
  • 确定最适合您的网站的缓存层次结构:比如第四点的图例。
  • 最大限度减少变动:某些资源的更新比其他资源频繁。 如果资源的特定部分(例如 JavaScript 函数或 CSS 样式集)会经常更新,可以考虑将其代码作为单独的文件提供。 这样一来,每次提取更新时,其余内容(例如变化不是很频繁的内容库代码)可以从缓存提取,从而最大限度减少下载的内容大小。

Ref