What
什么是 HTTP 缓存
Web 缓存(或 HTTP 缓存)是用于临时存储(缓存)Web 文档(如 HTML 页面和图像),以减少服务器延迟的一种信息技术。Web 缓存系统会保存下通过这套系统的文档的副本;如果满足某些条件,则可以由缓存满足后续请求。
Why
为什么要做 HTTP 缓存
- 提高响应速度和性能
- 节省服务器带宽
How
一、通过 ETag 验证缓存的响应
- 服务器使用 ETag HTTP 标头传递验证令牌。
- 验证令牌可实现高效的资源更新检查:资源未发生变化时不会传送任何数据。
第一次请求:
第二次请求:
二、Cache-Control
- 每个资源都可通过 Cache-Control HTTP 标头定义其缓存策略。
- Cache-Control 指令控制谁在什么条件下可以缓存响应以及可以缓存多久。
Cache-Control 包含的属性:
- no-cache:先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求。
- no-store:禁止浏览器以及所有中间缓存存储任何版本的返回响应。
- public:表示可被缓存、也可以不缓存,通常情况下并不是必须的,max-age 已经表明是否能被缓存。
- private:这些响应通常只为单个用户缓存,因此不允许任何中间缓存对其进行缓存,例如:个人数据。
- max-age:指定从请求的时间开始,允许提取的响应被重用的最长时间,单位:秒。
参数解读示范 👇
max-age=86400 | 浏览器以及任何中间缓存均可将响应缓存长达 1 天 |
---|---|
private, max-age=600 | 客户端的浏览器只能将响应缓存最长 10 分钟 |
no-store | 不允许缓存响应,每次请求都必须完整获取 |
三、最佳策略
四、如何更新、停用缓存
- 在资源“过期”之前,将一直使用本地缓存的响应。
- 通过在网址中嵌入文件内容指纹(文件名 hash 值),强制客户端更新到新版本的响应。
- 为获得最佳性能,每个应用都需要定义自己的缓存层次结构。
我们来分析上面这个例子:
- HTML 被标记为 no-cache,每次请求会验证文档是否变化(协商),如果变化了,则获取最新的。
- 允许浏览器和中间缓存(例如 CDN)缓存 CSS,并将 CSS 设置为 1 年后到期。
- JavaScript 设置为 1 年后到期,但标记为 private,它包含的某些用户私人数据是 CDN 不应缓存的。
- 图像缓存时不包含版本或唯一指纹,并设置为 1 天后到期。
技巧 组合使用 ETag、Cache-Control 和唯一网址来实现一举多得:较长的过期时间、控制可以缓存响应的位置以及随需更新。
五、Check List
在制定缓存策略时,需要牢记下面这些技巧和方法:
- 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次提取和存储这些内容。
- 服务器提供验证令牌 (ETag):有了验证令牌,当服务器上的资源未发生变化时,就不需要传送相同的字节。
- 确定中间缓存可以缓存哪些资源:对所有用户的响应完全相同的资源非常适合由 CDN 和中间缓存进行缓存。
- 为每个资源确定最佳缓存周期:不同的资源可能有不同的更新要求。 为每个资源审核并确定合适的 max-age。
- 确定最适合您的网站的缓存层次结构:比如第四点的图例。
- 最大限度减少变动:某些资源的更新比其他资源频繁。 如果资源的特定部分(例如 JavaScript 函数或 CSS 样式集)会经常更新,可以考虑将其代码作为单独的文件提供。 这样一来,每次提取更新时,其余内容(例如变化不是很频繁的内容库代码)可以从缓存提取,从而最大限度减少下载的内容大小。