前端浏览器缓存机制

前端浏览器缓存机制

写作背景

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

什么是浏览器缓存

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标签处理缓存冗余的问题。

相关推荐
若梦plus2 分钟前
PostgreSQL数据库基础
前端·数据库
若梦plus8 分钟前
微前端之ModuleFederation与qiankun对比
前端
若梦plus14 分钟前
事件驱动架构中微内核&插件化思想的应用
前端
胡西风_foxww29 分钟前
TypeScript 元组类型精简知识点
前端·typescript·类型·元祖
天天扭码43 分钟前
很全面的前端面试题——计算机网络篇(上)
前端·网络协议·面试
JSON_L1 小时前
Vue 详情模块 3
前端·javascript·vue.js
哀木1 小时前
关于 one drive 上传功能的前端接入(未完成)
前端
大熊学员2 小时前
HTML与JavaScript的羁绊
前端·css·html
Mike_Wuzy2 小时前
【前端】CSS基础知识及基本应用
前端·css