[TOC]

浏览器缓存机制(结合响应头)

以真实的用户请求举例。 假设明明同学访问:aaa网站 (此前从未访问过)

强烈建议先阅读 前篇 浏览器缓存的起点 -> Cache-Control

第一次访问aaa网站

肯定没有任何一个资源是有缓存的吗?

答案: 错

某些CDN或静态资源可能有缓存

解释: 假设(aaa网站 和 xxxxxx网站) 同时使用了CDN: <script src="https://cdn.jsdelivr.net/npm/vue"></script>
用户在访问aaa网站之前访问过了 xxxxxx网站,那就已经有CDN缓存了(一般CDN缓存是至少1年以上,1年内都有缓存)

对于从来没访问过的资源

顺序是:先memory 在disk 在发起请求

浏览器是先去缓存内找,没找到就正常发起请求,然后缓存到本地(具体是缓存到memory还是disk,浏览器会根据当前的内存空间情况和资源大小,按情况缓存,为了方便介绍,此后统称缓存)

浏览器在缓存资源时,会计算出过期时间(强制缓存生效时间内),效果类似 响应头的Expires字段

如何计算的? 根据响应头Cache-Control 具体请看 作者bigtree 上一篇文章 浏览器缓存的起点 -> Cache-Control

第二次以后访问aaa网站

强制缓存

以 main.xx.js 举例,浏览器在发起请求前会先去缓存内找。拿到了之后,检查过期时间,未过期则进入 强制缓存,已过期则进入 协商缓存

协商缓存

作用: 确认一下资源是否过期(需对服务端发起请求,只不过是header请求,更轻量),如果没过期则继续用本地缓存

获取到新的响应头后,会对比Etag(指纹)或last-modified(最后修改时间)。如果没过期则继续用本地缓存,过期则重新发请求

注:如果进入了强制缓存,是不会发起协商缓存的,直接就响应资源。(可能导致资源不能及时更新,所以要根据需求,定制准确的 前端缓存策略 文章待出 )

实际问题

如何做到既不重新部署web,也能响应到最新的静态资源,也能保留资源的浏览器缓存?

比如:我的web项目,有个语言包 zh.json,假设里面是我的菜单,及菜单介绍。我如何做到不重新发布web项目,也能让zh.json的更改生效,同时还能保留浏览器对zh.json的缓存

答:可以设置7天过期时间(更改更频繁的话,可以设更小) Cache-Control: max-age=604800 (7天之后,浏览器就会发起预检请求,去检测资源是否改变,已改变则重新获取zh.json)

附几张流程图

浏览器缓存机制(结合响应头) - 图1


(原创整理,有疑问或错误可以留言。如果有用,谢谢点赞~)


性能优化合集快速入口: