HTTP 缓存策略:强缓存和协商缓存

简介: 前端西瓜哥

大家好,我是前端西瓜哥。今天讲一下 HTTP 缓存策略的强缓存和协商缓存。

缓存是什么?

缓存(Cache)是一种数据存储技术,广泛应用在电脑工程领域。

它将原本访问起来较慢的数据,放到访问更快的存储介质中,当第二次访问时,能够更快地访问数据,是一种 空间换时间 的做法。

比如,有个文件经常被读取,且很少改变,那我们就直接将其缓存到内存中,节省掉耗时的 IO 磁盘读取时间。

再比如,在写代码时,我们的一个方法会接受参数,然后计算返回一个结果,假设这个计算过程非常耗时,且结果值只依赖传入的参数。

那我们就可以将参数和结果的对应映射,保存到哈希表中,下次如果是相同参数,就能命中然后直接从哈希表里获取,速度有了极大提升。

HTTP 缓存也是一样的道理,用户通过 HTTP 请求访问的资源会缓存到本地,在用户第二次访问相同资源时,直接使用之前缓存的资源。

当然资源可能并不一定是不变的,在必要的时候需要更新缓存。为此我们可能需要设置一下缓存的有效期,或是发送一个占用带宽小的请求询问服务端等等。

这些,就是 HTTP 缓存策略

强缓存

强缓存,指的是 让浏览器强制缓存服务端提供的资源

“东西就给你了,没事别找我。”

Cache-Control: max-age=<seconds>

响应头字段 Cache-Control,通过设置 max-age=<seconds>,可以规定资源的缓存有效时间长度,单位为秒。

需要注意的是 Cache-Control 是通用头字段,请求头和响应头中都可以使用。

响应头字段的 Cache-Control 用于告知客户端如何缓存资源。

客户端的 Cache-Control 则是告知服务器需要多新鲜的资源,比如 no-cache 或 max-age=0 表示要最新鲜的资源。

Cache-Control: max-age=31536000

在浏览器 devtool 的 network 面板,我们看到 from disk cache 的字样,代表这个资源并没有去发送请求,而是使用了来自硬盘的缓存。

如果你不停地刷新页面,你还会看到 from memory cache :来自内存的缓存。因为刷新前资源正在使用,还在内存中,刷新后浏览器就直接从内存中取出来了。

当你强制刷新时,浏览器会在请求头中加上 Cache-Control: no-cache 或是 Cache-Control: max-age=0,要求服务端返回最新资源。

Expires

Cache-Control: max-age=<seconds> ,是缓存的有效时长。

当看到一个叫 max-age(有效时长)的东西时,我们经常会发现它的孪生兄弟:Expires(过期时间点)。如果你熟悉 Cookies,你会发现 Cookies 也有这么一对属性。

Expires: Wed, 21 Oct 2015 07:28:00 GMT

Expires 使用的 GMT 格式的时间戳字符串。

当 max-age 和 Expires 都存在时,使用 max-age。这点和 Cookies 一样。

强缓存,就是让浏览器将资源缓存下来,在缓存过期前,不发送请求获取新资源,而是直接使用本地资源。

协商缓存

协商缓存,是在缓存过期的情况下,客户端和服务端协商,确认客户端缓存是否需要更新

Last-Modified 和 If-Modified-Since

响应头字段 Last-Modified 表示提供的资源最后被修改的时间。值是 GMT 格式的字符串。

Last-Modified: Sat, 09 Apr 2022 14:47:36 GMT

这个时间会标记在对应缓存上,起到标识的作用

当浏览器的缓存失效后,会再次请求服务端,并带上 If-Modified-Since 请求头字段,它的值就是之前 Last-Modified 带过来的值。

If-Modified-Since: Sat, 09 Apr 2022 14:47:36 GMT

当服务端发现资源最后修改时间和  If-modified-since 值相等,代表资源从该时间后再未改变过。

服务端于是返回 304(Not Modified)状态码,表示资源没有改变,并且响应体为空。浏览器拿到后,就知道原本可能过期的缓存其实还可以继续使用。

如果资源改变了,就会返回 200,且响应体带上最新资源。

ETag 和 If-None-Match

除了用 Last-Modified 代表的资源最后修改时间作为标识,我们还可以使用 ETag 响应头。

ETag 的值没有规定,你可以是时间戳的哈希值,也可以是版本号。

另外 ETag 分为强 ETag 和弱 ETag,其中弱 ETag 以为 W/ 开头。

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"

然后和 If-Modified-Since 一样,当缓存过期时,客户端会在请求头带上 If-None-Match 去请求资源。

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

如果资源依旧新鲜,则返回 304,客户端继续复用本地资源。

结尾

强缓存,设置一个过期时间,让客户端在过期前使用本地缓存,直到过期才请求更新鲜的资源。涉及的头字段有 Cache-Control: max-age=<seconds>  或 Expires

协商缓存,在客户端缓存过期的情况下,和服务端协商一下,是否可以继续使用本地缓存。涉及的头字段有 Last-Modified / If-Modified-SinceETag / If-None-Match

不过需要注意的是,这些都只是规范,我们无法确定客户端或服务端在实现上完全遵循,而且可能在版本更新中会出现一些 bug。

所以对于发生变化的文件,我更倾向于给文件名加上哈希串。毕竟,访问一个从来没访问过的资源,客户端是不会有缓存的。这样就能绕开缓存机制,真正拿到最新资源,而不会掉入缓存陷阱。

参考

相关文章

相关文章
|
3月前
|
缓存 负载均衡 网络协议
电商API接口性能优化技术揭秘:缓存策略与负载均衡详解
电商API接口性能优化是提升系统稳定性和用户体验的关键。本文聚焦缓存策略与负载均衡两大核心,详解其在电商业务中的实践。缓存策略涵盖本地、分布式及CDN缓存,通过全量或部分缓存设计和一致性维护,减少后端压力;负载均衡则利用反向代理、DNS轮询等技术,结合动态调整与冗余部署,提高吞吐量与可用性。文中引用大型及跨境电商平台案例,展示优化效果,强调持续监控与迭代的重要性,为电商企业提供了切实可行的性能优化路径。
|
4月前
|
缓存 搜索推荐 CDN
HTTP缓存策略的区别和解决的问题
总的来说,HTTP缓存策略是一种权衡,需要根据具体的应用场景和需求来选择合适的策略。理解和掌握这些策略,可以帮助我们更好地优化网页性能,提高用户的浏览体验。
116 11
|
3月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
126 0
|
6月前
|
数据采集 缓存 JavaScript
数据抓取的缓存策略:减少重复请求与资源消耗
本教程聚焦于提升爬虫效率与稳定性,通过结合缓存策略、代理IP技术(如爬虫代理)、Cookie和User-Agent设置,优化数据采集流程。以知乎为例,详细讲解如何抓取指定关键词的文章标题和内容。内容涵盖环境准备、代码实现、常见问题及解决方案,并提供延伸练习,帮助读者掌握高效爬虫技巧。适合具备Python基础的初学者,助你规避网站机制,顺利获取目标数据。
158 2
数据抓取的缓存策略:减少重复请求与资源消耗
|
10月前
|
Web App开发 缓存 UED
如何设置浏览器的缓存策略?
【10月更文挑战第23天】通过合理地设置浏览器的缓存策略,可以在提高网页性能、减少网络流量的同时,确保用户能够获取到最新的内容,从而提升用户体验和网站的性能优化效果。
756 60
|
9月前
|
缓存 API C#
C# 一分钟浅谈:GraphQL 中的缓存策略
本文介绍了在现代 Web 应用中,随着数据复杂度的增加,GraphQL 作为一种更灵活的数据查询语言的重要性,以及如何通过缓存策略优化其性能。文章详细探讨了客户端缓存、网络层缓存和服务器端缓存的实现方法,并提供了 C# 示例代码,帮助开发者理解和应用这些技术。同时,文中还讨论了缓存设计中的常见问题及解决方案,如缓存键设计、缓存失效策略等,旨在提升应用的响应速度和稳定性。
117 13
|
10月前
|
存储 缓存 安全
在 Service Worker 中配置缓存策略
Service Worker 是一种可编程的网络代理,允许开发者控制网页如何加载资源。通过在 Service Worker 中配置缓存策略,可以优化应用性能,减少加载时间,提升用户体验。此策略涉及缓存的存储、更新和检索机制。
|
9月前
|
存储 消息中间件 设计模式
缓存数据一致性策略如何分类?
数据库与缓存数据一致性问题的解决方案主要分为强一致性和最终一致性。强一致性通过分布式锁或分布式事务确保每次写入后数据立即一致,适合高要求场景,但性能开销大。最终一致性允许短暂延迟,常用方案包括Cache-Aside(先更新DB再删缓存)、Read/Write-Through(读写穿透)和Write-Behind(异步写入)。延时双删策略通过两次删除缓存确保数据最终一致,适用于复杂业务场景。选择方案需根据系统复杂度和一致性要求权衡。
235 0
|
10月前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
164 10
|
10月前
|
存储 消息中间件 缓存
缓存策略
【10月更文挑战第25天】在实际应用中,还需要不断地监控和调整缓存策略,以适应系统的变化和发展。