HTTP Web 缓存总结

HTTP Web 缓存总结
Photo by Sam 🐷 / Unsplash

友情提示:缓存什么的,是完全依赖相关http header头信息来标记和判断的

缓存读取顺序:

首先读取本地缓存,如果条件满足就取本地缓存,否则往后走代理缓存,同理,条件满足就是从代理缓存取资源(可能存在多级代理缓存)

如果一条链路上的资源都不符合,那么就去源服务器获取

缓存优先级:Cache-Control > Expires > Etag > Last-Modified

缓存的分类和优先级

  • 强缓存 状态码 200 (比如 200 (from cache))
    • Expires 服务器下发的绝对时间,而判断的时候以浏览器时间为准,客户端和服务器有可能会不一样
    • Cache-Control 相对时间,以客户端相对时间为准
  • 协商缓存 状态码 304
    • Last-Modified If-Modified-Since
    • Etag If-None-Match

强缓存优先级高于协商缓存,强缓存不会询问服务器,直接使用缓存。协商缓存会询问服务器关于文件的可用性

对于传输过程中的中间节点,本文都称为代理服务器,包括proxy、CDN和缓存服务器

缓存头Cache-Control

可缓存性 (哪些节点可以进行缓存)

  • public 在这个请求的返回过程中的任何节点都可以对这个返回的内容进行缓存,比如代理服务器可以对其缓存
  • private 只有发起请求的节点才能进行缓存,其他节点都禁止缓存资源
  • no-cache 可以进行缓存,但是在使用之前,要去服务器先验证缓存的有效性,有效的话才能使用,搭配max-age=0使用,不会直接从浏览器读取相应的缓存文件,而是先向服务端发起请求确认浏览器的缓存是否过期来判断是从浏览器加载还是从服务器加载
  • no-store 任何节点都不能进行缓存

到期时间

  • max-age = 多少秒之后缓存内容过期
  • s-maxage = 只在代理服务器生效。优先级大于max-age。如果s-maxage时间到了,代理服务器会去远端读取新的数据并更新缓存
  • max-stale = 即便缓存过期了,只要在max-stale的范围,则不需要请求新的缓存

重新验证

  • must-revalidate 在设置了max-age过期之后,浏览器必须去源服务端获取新的数据
  • proxy-revalidate 代理服务器数据过期后,必须去源服务端获取新的数据

其他

  • no-transform 用在代理服务器,不允许对返回内容进行压缩、格式转换等

上述头信息是规范,但是很多代理服务器不按这个来

缺点:Cache-Control为客户端缓存,服务端更新了文件之后,客户端并不第一时间更新缓存,这也是web开发中的常见问题

Cache-Control缺点的通用解决方案:在打包文件之后,根据静态文件内容加上一串hash码或者版本号,如果静态文件内容没变,则hash不会变,反之,静态文件内容变化之后,hash码变化,则静态资源url发生变化,可以更新客户端缓存

举例

我司的处理:可以看到,devTools的Size栏,提示出from memory cache,即读取浏览器本地缓存

image.png
示例代码:这里是用模板来加载的,support来填充,猜测可以在初始化请求的时候,通过请求配置接口,拿到对应的web资源的版本号的接口或者配置文件,然后再静态资源去加载之前,将对应的版本号填充到对应的src或者link中

资源验证头信息Last-Modified和Etag

Last-Modified

资源上次修改时间,主要配合If-Modified-Since或者If-Unmodified-Since使用:如果请求了一个资源的respose header里面有Last-Modified头信息指定了一个时间,下一次浏览器发起请求的时候,通过If-Modified-Since或者If-Unmodified-Since(通常使用If-Modified-Since,If-Unmodified-Since很少用)带上那个时间,带到服务器,服务器读取并对比这个资源上次修改的时间,如果一致,则代表资源没有被修改过,那么浏览器可以继续使用缓存,反之缓存不能使用

ps:如果资源是存在数据库的,可以给资源加上一个update-at的字段加上修改时间作为Last-Modified时间返回给浏览器

Etag

更加严格的验证方式,通过数据签名的方式,根据资源的内容产生一个唯一的签名,如果资源的内容产生了修改,那么签名就会更新,任何的修改都会导致签名不一致,常用方式是对资源的内容进行hash计算产生签名来标记资源。

配合If-Match或者If-Non-Match使用,下一次浏览器发请求会带上If-Match或者If-Non-Match头,头里面的值就是服务端上一次给出的Etag签名,然后服务器对比签名是否一致

http code 304资源没有修改,可以直接读取缓存,及时这时候服务端有了新的返回,也会被浏览器忽略,直接读取缓存数据(写个接口,而不是静态资源文件来验证一下)

tips:

chrome的devTools,当把Disable cache勾选上之后,浏览器就不往服务器发送关于缓存的头信息了,这时候只能从服务器读取最新的数据

缓存对比localStorage: 缓存文件不用自己去控制localStorage的读写呢
image.png

本文是 18年我发布在 Segmentfault 社区的,时间过得真快

Read more

RAG不是万能的,附常见误解与澄清

RAG不是万能的,附常见误解与澄清

能给人理清目前 AI 在生产落地的问题,是一件难能可贵的事情,AI 在生产落地会有哪些阻碍的讲解,讲干货的真的是很少,至少我自己曾经在这个问题上困惑了很久。 因为之前我在 AI 电商团队,做具体的 AI Sass 落地的时候,团队经常会沟通做到生产级可用的 AI,需要哪些东西,大概的门槛还是了解到一些的,我的能力也顶多在应用层面去做一些工作量的定制与代码衔接,涉及到模型层面,一概歇菜,很多人估计只是想着,写一个 Prompt ,就是真正的拥抱 AI 了。 当我看到自媒体里面铺天盖地的在讲 AI 如何帮助企业提效,如果重塑行业的时候,有种很复杂的感觉,他们真的懂 AI 吗,甚至他们真的懂软件吗? 基本上现在大家接触到的方式就几种: * 割韭菜卖课,讲概念,前景,这些基本上都是拿别人的产品来给自己做嫁衣,自己顶多是个工具的使用者和营销者,比如用 Midjourney,Kimi,豆包,海螺什么的,告诉大家用了就能提效,获得流量,

Shopify 构建商城页面的几种方式

Shopify 构建商城页面的几种方式

当用户需要对 Shopify 商城页面有自定义的需求时,一般会选择: 1、直接使用官方商城的 theme 来构建,可以使用,但是免费模板较少,只有 13 个。 2、使用第三方 theme 来构建,也有很多的模板可以选择,比如 envato 上有数百个 shopify 的模板,这是个非常大的市场。 3、完全自定义开发,自由度最高 当用户对 Shopify 商城页面,有完全自定义的需求,通常是常规主题无法满足需求,推荐使用 Shopify Hydrogen 的官方方案,开发人员可以对商城进行完全的页面级别的自定义。 而对于开发人员来说,官方的 Shopify Liquid 开发起来的效率和体验,是不如 Shopify Hydrogen 来的舒服,而且使用 Shopify Hydrogen ,还可以对性能有提升,

Meepo 要找一份远程前端(全栈)开发的工作

Meepo 要找一份远程前端(全栈)开发的工作

为什么找远程岗位 我一直是比较喜欢远程合作的方式,基本上从事远程开发的团队,都是奔着做事去的,大家能筛选到一起,为一个目标而努力,是一件很难得的事情,远程协作的方式,在自由度和产出之间能保持非常好的平衡,没有必要在通勤以及办公室的无效沟通上浪费太多的时间。 技术特点如何 前端: React + TypeScript 生态体系,常规的网页开发,浏览器插件,Electron 客户端开发都 OK,对各种前端技术方案有一定的沉淀和实践。 后端: Nextjs + Nestjs 开发全栈站点及后端 API 服务 个人特点 即插即用,对于大多数的前端场景和技术方案,都有所涉及。 多年的开发经验,对企业自有产品开发,大客户定制,以及独立开发,有一定的观察和沉淀。 拥抱 AI,对当下比较热门的 AI 技术有一定的了解和沉淀。 喜欢分享和交流,对技术和业务,以及营销都感兴趣。 之前接触的一些业务形态 公司层面: 主要是国内客服领域,涉及到全流程客服,IM,音视频等

从事 SEO 12 年的大佬总结的要点

从事 SEO 12 年的大佬总结的要点

从事 SEO 12 年后,以下是我能想到的所有 SEO 技巧: 1. 在 H1、H2 和 URL 部分中使用主要关键词。 2. 停止追逐虚荣指标。流量固然重要,但转化率才是最重要的。 3. 内部链接可以将“几乎完成”的页面转变为表现最佳的页面。 4. 定期检查你的网站是否有坏链接,这是一个简单的 SEO 胜利。 5. Google Search Console 是您最好的朋友,使用它来重新优化排名在第 3-7 位的页面。 6. 90% 的反向链接应来自相关的高权威网站。 7. 速度决定一切——或许应该说,速度不足会扼杀一切。确保加载时间在 2 秒以内。 8. 持续更新内容将帮助你的页面保持更高的排名。 9. 使用 NLP