前端浏览器缓存机制

前端浏览器缓存机制

写作背景

当测试环境前端资源有更新的时候,我们想要测试刚刚部署上去的新功能,或者打的热补丁的效果,却发现前端文件被浏览器缓存了下来,加载的还是上一个版本的文件。

什么是浏览器缓存

Web浏览器在访问网页时会将某些资源(例如HTML、CSS、JavaScript、图像等)保存在本地存储器中,以便在将来的访问中可浏览器缓存以更快地加载和显示页面。

浏览器缓存的基本工作原理

当浏览器首次请求一个网页时,它会将服务器返回的资源保存在本地缓存中,并在后续的请求中使用缓存的资源,而不是再次从服务器下载相同的资源。

当用户再次访问同一网页时,浏览器会首先检查本地缓存,如果资源没有过期或被修改,浏览器将直接从缓存中加载资源。

如何判断资源有没有过期或被修改

  • HTTP协议的缓存机制
  • 文件指纹
  • 缓存清除
HTTP协议的缓存机制

HTTP缓存可以分为

  1. 强缓存: 浏览器会直接从本地缓存中加载资源,而不会向服务器发送请求
  2. 协商缓存:通过在浏览器请求资源时,与服务器进行一系列的交互,以确定是否需要重新传输资源
强缓存

通过响应头携带字段来确定,http1.0阶段是通过Expires字段,后来的http1.1中使用Cache-Control字段

Expries:如果浏览器再次请求该资源,并且当前时间早于或等于过期时间,浏览器将直接从缓存中加载该资源,而不发送请求给服务器。

ini 复制代码
Expries: Thu, 01 Dec 1994 16:00:00 GMT 
=> 资源的过期时间是1994年12月1日下午4点(格林尼治标准时间)

Cache-Control

markdown 复制代码
"no-store":该指令指示浏览器不应该将任何响应内容存储在缓存中。每次请求该资源时,都需要向服务器发送请求并获取完整的响应。这样可以确保每次都获取到最新的资源,适用于对安全性要求较高、敏感数据或私密信息的资源。
"no-cache":该指令要求浏览器在使用缓存之前先向服务器发送请求进行验证。浏览器会向服务器发送一个条件请求,服务器会检查资源是否发生了变化。如果资源未发生变化,则服务器返回状态码304(Not Modified),浏览器使用缓存的资源。如果资源发生了变化,服务器会返回新的资源。这样可以确保浏览器使用的是最新的资源。
"must-revalidate":该指令要求浏览器在使用缓存之前,必须先向服务器发送请求进行验证。类似于"no-cache",浏览器会发送条件请求,服务器进行资源验证。如果资源仍然有效(未发生变化),服务器返回状态码304,浏览器使用缓存的资源。如果资源过期或发生了变化,服务器会返回新的资源。与"no-cache"不同的是,"must-revalidate"指令强制浏览器进行验证,而不是根据缓存的过期时间来决定是否发送请求。
  • 两者同时存在,Cache-Control优先级高于Expires
协商缓存

由HTTP协议的缓存机制中的"Cache-Control"和"ETag"、"Last-Modified"等响应头字段进行控制和实现的

协商缓存通过比较资源的特定标识符(如ETag)或最后修改时间(Last-Modified)来判断资源是否需要重新传输,而不是每次都传输整个资源。这减少了数据传输量和网络延迟,提高了性能和效率。

ETag: 根据文件的具体内容生成哈希值,能够具体追踪到资源内容细粒度级别的变化。

Last-modified: 通过时间点来感知,如果在单位时间内修改多次,此时就不能体现修改。

同一个接口,第一次请求的时候,服务器在响应头里面设置ETag和Last-Modified,当下次发送相同的请求时,在请求头If-Modified-Since 和 If-None-Match中带上之前Last-Modified和ETag的值。

服务器拿到这2个值结合自身的实际情况判断,如果还是没有变更则告诉浏览器(code 304)这个文件没有变化,你可以继续使用缓存中的资源,并且更新expirescache-control,让这个文件再次缓存服务器设置的时间。如果有变更了,则把新的资源重新返回给客户端(code 200),客户端重新缓存新的资源。

缓存清除

在html文件中使用meta标签,设置http-equiv属性和相关的值,来模拟HTTP响应头的一些指令和控制缓存行为。

html 复制代码
// 资源立即过期
<meta http-equiv="Expires" content="0" >
// 模拟HTTP响应头中的"Pragma"字段,指示浏览器不要缓存该页面。
<meta http-equiv="Pragma" content="no-cache" >
// 模拟HTTP响应头中的"Cache-Control"字段,指示浏览器不要缓存该页面。
<meta http-equiv="Cache-control" content="no-cache" >
// 浏览器应立即将此资源视为过期
<meta http-equiv="Cache" content="no-cache" >
使用webWorker轮询

安装worker-loader 插件

解决思路参考:juejin.cn/post/718545...

总结

强缓存不适合于静态页面的缓存, 如果页面都缓存了,当测试环境资源包更新了,我们访问也是走的缓存数据,这样看不到最新的内容了

可以通过webpack,抽离第三方插件以及图片等静态资源(将其进行缓存),将开发的HTML页面后缀拼上哈希值,这样每次打包,生成的资源名字不一样,则浏览器就会重新从服务器中请求数据。

如果没有进行分包操作,会使浏览器默认将资源进行缓存,这时候可以使用协商缓存或者meta标签处理缓存冗余的问题。

相关推荐
岁岁种桃花儿8 分钟前
Vue核心语法第一篇:Vue是什么?
前端·javascript·vue.js
观无1 小时前
若依EasyExcel实现单元格合并
开发语言·前端·javascript
愚公搬代码1 小时前
【愚公系列】《Web应用安全》001-VMware的安装
前端·安全
xiaohaiAIgeo1 小时前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识
立少→万能汉编1 小时前
用“立少→超文本”写静态网页,标签<倍>
服务器·前端·javascript
weixin_431600441 小时前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
你挚爱的强哥2 小时前
【chromeDownload】自定义组件:多用于登录框底部提供下载Chrome谷歌浏览器的链接
前端·vue.js·chrome
cindershade2 小时前
用原生 HTML5 视频与 Canvas 实现浏览器端视频抽帧封面
前端
笨鸟先飞,勤能补拙2 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
NutShell Wang2 小时前
Wails v3 Beta 实战:用显式对象模型重写你的第一个 Go 桌面应用
前端·人工智能·go·vibe coding