Skip to content

Commit 145f043

Browse files
author
tianzhao
committed
add force refresh btn
1 parent 90f4853 commit 145f043

File tree

4 files changed

+254
-14
lines changed

4 files changed

+254
-14
lines changed

cache-management.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# 缓存管理指南
2+
3+
## 问题描述
4+
5+
当您修改了 JavaScript 代码后,可能会遇到以下情况:
6+
- 页面没有反映最新的代码更改
7+
- 功能表现与预期不符
8+
- 控制台显示旧版本的日志信息
9+
10+
这通常是由于浏览器缓存或 Service Worker 缓存导致的。
11+
12+
## 解决方案
13+
14+
### 1. 使用强制刷新按钮(推荐)
15+
16+
在参数控制面板中,我们添加了一个红色的**"强制刷新"**按钮:
17+
- 点击该按钮会清除所有缓存并重新加载页面
18+
- 确保获取最新版本的 JavaScript 代码
19+
- 适用于开发和生产环境
20+
21+
### 2. 使用键盘快捷键
22+
23+
按下 `Ctrl + Shift + R`
24+
- 快速触发强制刷新功能
25+
- 与强制刷新按钮效果相同
26+
- 开发者友好的快捷操作
27+
28+
### 3. 浏览器原生方法
29+
30+
#### Chrome/Edge:
31+
- `Ctrl + Shift + R``Ctrl + F5`:硬刷新
32+
- `F12` 打开开发者工具 → Network 标签 → 勾选 "Disable cache"
33+
34+
#### Firefox:
35+
- `Ctrl + Shift + R``Ctrl + F5`:硬刷新
36+
- `F12` 打开开发者工具 → Network 标签 → 点击设置图标 → 勾选 "Disable Cache"
37+
38+
#### Safari:
39+
- `Cmd + Shift + R`:硬刷新
40+
- 开发菜单 → 清空缓存
41+
42+
### 4. 手动清除浏览器缓存
43+
44+
#### Chrome/Edge:
45+
1.`Ctrl + Shift + Delete`
46+
2. 选择时间范围
47+
3. 勾选 "缓存的图片和文件"
48+
4. 点击 "清除数据"
49+
50+
#### Firefox:
51+
1.`Ctrl + Shift + Delete`
52+
2. 选择要清除的时间范围
53+
3. 勾选 "缓存"
54+
4. 点击 "立即清除"
55+
56+
## 技术实现
57+
58+
### Service Worker 缓存策略
59+
60+
我们实现了智能缓存策略:
61+
62+
1. **JavaScript 文件**:使用网络优先策略
63+
- 优先从网络获取最新版本
64+
- 网络失败时回退到缓存
65+
- 确保 JS 代码始终是最新的
66+
67+
2. **其他资源**:使用缓存优先策略
68+
- 提高加载速度
69+
- 减少网络请求
70+
- 保持离线可用性
71+
72+
### 缓存版本管理
73+
74+
- Service Worker 使用版本号 `pose-estimator-v1.0.1`
75+
- 每次更新会自动清理旧缓存
76+
- 支持强制清除所有缓存
77+
78+
### 自动更新检测
79+
80+
- 检测到新版本时会提示用户更新
81+
- 支持静默更新和手动确认更新
82+
- 更新完成后自动重新加载页面
83+
84+
## 开发建议
85+
86+
### 1. 开发环境
87+
88+
在本地开发时:
89+
```javascript
90+
// 在控制台中禁用缓存
91+
if (window.location.hostname === 'localhost') {
92+
console.log('开发模式:建议在开发者工具中禁用缓存');
93+
}
94+
```
95+
96+
### 2. 版本控制
97+
98+
每次发布新版本时:
99+
1. 更新 Service Worker 中的 `CACHE_NAME` 版本号
100+
2. 测试强制刷新功能
101+
3. 验证缓存清理是否正常工作
102+
103+
### 3. 调试技巧
104+
105+
使用浏览器开发者工具:
106+
1. **Application/应用** 标签 → **Service Workers**
107+
- 查看 Service Worker 状态
108+
- 手动注销和重新注册
109+
110+
2. **Application/应用** 标签 → **Storage**
111+
- 查看缓存内容
112+
- 手动删除特定缓存
113+
114+
3. **Network/网络** 标签
115+
- 监控资源加载
116+
- 检查缓存命中情况
117+
118+
## 常见问题
119+
120+
### Q: 强制刷新后仍然看到旧代码?
121+
A: 可能需要:
122+
1. 完全关闭浏览器重新打开
123+
2. 检查是否有多个标签页打开
124+
3. 清除浏览器的所有数据
125+
126+
### Q: Service Worker 无法注册?
127+
A: 确保:
128+
1. 使用 HTTPS 或 localhost
129+
2. Service Worker 文件路径正确
130+
3. 浏览器支持 Service Worker
131+
132+
### Q: 缓存清除功能不工作?
133+
A: 检查:
134+
1. 浏览器控制台是否有错误
135+
2. Service Worker 是否正常运行
136+
3. 网络连接是否正常
137+
138+
## 最佳实践
139+
140+
1. **开发时**:始终在开发者工具中禁用缓存
141+
2. **测试时**:使用强制刷新功能验证更新
142+
3. **部署时**:更新 Service Worker 版本号
143+
4. **用户反馈**:提供清晰的缓存清理指导
144+
145+
## 监控和日志
146+
147+
应用会在控制台输出相关日志:
148+
```
149+
Service Worker: 安装中...
150+
Service Worker: 缓存文件
151+
Service Worker: 激活中...
152+
Service Worker: 删除旧缓存
153+
缓存已清除,正在刷新页面...
154+
```
155+
156+
通过这些日志可以了解缓存管理的执行情况。

main.html

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ <h3 style="display: inline-block; margin-right: 15px;">One Euro Filter 参数设
5757
<span style="font-size: 12px; color: #666;">Hz</span>
5858
</div>
5959
</div>
60-
<button id="applyParams" style="margin-top: 10px; padding: 8px 16px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">应用参数</button>
61-
<button id="resetParams" style="margin-left: 10px; padding: 8px 16px; background-color: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer;">重置默认值</button>
60+
<div style="margin-top: 10px;">
61+
<button id="applyParams" style="padding: 8px 16px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">应用参数</button>
62+
<button id="resetParams" style="margin-left: 10px; padding: 8px 16px; background-color: #6c757d; color: white; border: none; border-radius: 4px; cursor: pointer;">重置默认值</button>
63+
<button id="forceRefresh" style="margin-left: 10px; padding: 8px 16px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer;" title="清除缓存并刷新页面,获取最新代码">强制刷新</button>
64+
</div>
6265
</div>
6366
</div>
6467

@@ -96,6 +99,14 @@ <h3 style="display: inline-block; margin-right: 15px;">One Euro Filter 参数设
9699
navigator.serviceWorker.addEventListener('controllerchange', () => {
97100
window.location.reload();
98101
});
102+
103+
// 监听Service Worker消息
104+
navigator.serviceWorker.addEventListener('message', (event) => {
105+
if (event.data && event.data.type === 'CACHE_CLEARED') {
106+
console.log('缓存已清除,正在刷新页面...');
107+
window.location.reload();
108+
}
109+
});
99110
}
100111

101112
// PWA安装提示
@@ -142,6 +153,41 @@ <h3 style="display: inline-block; margin-right: 15px;">One Euro Filter 参数设
142153
installButton.remove();
143154
}
144155
});
156+
157+
// 强制刷新缓存功能
158+
document.addEventListener('DOMContentLoaded', () => {
159+
const forceRefreshBtn = document.getElementById('forceRefresh');
160+
if (forceRefreshBtn) {
161+
forceRefreshBtn.addEventListener('click', () => {
162+
if (confirm('这将清除所有缓存并刷新页面,确定要继续吗?')) {
163+
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
164+
// 通知Service Worker清除缓存
165+
navigator.serviceWorker.controller.postMessage({ type: 'FORCE_REFRESH' });
166+
} else {
167+
// 如果没有Service Worker,直接强制刷新
168+
window.location.reload(true);
169+
}
170+
}
171+
});
172+
}
173+
});
174+
175+
// 键盘快捷键:Ctrl+Shift+R 强制刷新
176+
document.addEventListener('keydown', (event) => {
177+
if (event.ctrlKey && event.shiftKey && event.key === 'R') {
178+
event.preventDefault();
179+
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
180+
navigator.serviceWorker.controller.postMessage({ type: 'FORCE_REFRESH' });
181+
} else {
182+
window.location.reload(true);
183+
}
184+
}
185+
});
186+
187+
// 开发模式检测:如果URL包含localhost或127.0.0.1,显示开发提示
188+
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
189+
console.log('开发模式:使用 Ctrl+Shift+R 或点击"强制刷新"按钮来获取最新代码');
190+
}
145191
</script>
146192
</body>
147193
</html>

main.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
class PoseEstimator {
22
constructor(canvasElement) {
3+
this.video = null; // 将在_setupCamera中创建
34
this.canvas = canvasElement;
45
this.ctx = this.canvas.getContext('2d');
5-
this.video = null; // 内部创建的video元素,不显示
66
this.detector = null;
77
this.poseFilters = null;
88
this.lastFilteredPose = null; // 用于存储上一帧的滤波结果
@@ -155,7 +155,7 @@ class PoseEstimator {
155155
const timestamp = performance.now() / 1000.0;
156156

157157
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
158-
this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
158+
// 不绘制视频背景,只显示姿态估计结果
159159

160160
frameCount++;
161161

@@ -205,8 +205,8 @@ class PoseEstimator {
205205

206206
this._drawKeypoints(this.lastFilteredPose.keypoints);
207207
this._drawSkeleton(this.lastFilteredPose.keypoints);
208-
} else if (frameCount % 30 === 0) {
209-
console.log('未检测到姿态');
208+
// } else if (frameCount % 30 === 0) {
209+
// console.log('未检测到姿态');
210210
}
211211

212212
// 记录整帧处理完成时间
@@ -221,13 +221,13 @@ class PoseEstimator {
221221
this._drawPerformanceInfo(poseDetectionDuration, renderingDuration, totalDuration, frameCount);
222222

223223
// 每30帧输出一次耗时统计到控制台
224-
if (frameCount % 30 === 0) {
225-
console.log(`=== 第${frameCount}帧耗时统计 ===`);
226-
console.log(`姿态检测耗时: ${poseDetectionDuration.toFixed(2)}ms`);
227-
console.log(`渲染绘制耗时: ${renderingDuration.toFixed(2)}ms`);
228-
console.log(`总处理耗时: ${totalDuration.toFixed(2)}ms`);
229-
console.log(`帧率: ${(1000 / totalDuration).toFixed(1)} FPS`);
230-
}
224+
// if (frameCount % 30 === 0) {
225+
// console.log(`=== 第${frameCount}帧耗时统计 ===`);
226+
// console.log(`姿态检测耗时: ${poseDetectionDuration.toFixed(2)}ms`);
227+
// console.log(`渲染绘制耗时: ${renderingDuration.toFixed(2)}ms`);
228+
// console.log(`总处理耗时: ${totalDuration.toFixed(2)}ms`);
229+
// console.log(`帧率: ${(1000 / totalDuration).toFixed(1)} FPS`);
230+
// }
231231

232232
requestAnimationFrame(frame);
233233
} catch (error) {

sw.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const CACHE_NAME = 'pose-estimator-v1.0.0';
1+
const CACHE_NAME = 'pose-estimator-v1.0.1';
22
const urlsToCache = [
33
'/main.html',
44
'/main.js',
@@ -49,6 +49,32 @@ self.addEventListener('fetch', event => {
4949
return;
5050
}
5151

52+
// 对于JS文件,使用网络优先策略确保获取最新版本
53+
if (event.request.url.endsWith('.js') && !event.request.url.includes('cdn.jsdelivr.net')) {
54+
event.respondWith(
55+
fetch(event.request)
56+
.then(response => {
57+
// 如果网络请求成功,更新缓存并返回
58+
if (response && response.status === 200) {
59+
const responseToCache = response.clone();
60+
caches.open(CACHE_NAME)
61+
.then(cache => {
62+
cache.put(event.request, responseToCache);
63+
});
64+
return response;
65+
}
66+
// 网络失败时回退到缓存
67+
return caches.match(event.request);
68+
})
69+
.catch(() => {
70+
// 网络完全失败时使用缓存
71+
return caches.match(event.request);
72+
})
73+
);
74+
return;
75+
}
76+
77+
// 对于其他资源,使用缓存优先策略
5278
event.respondWith(
5379
caches.match(event.request)
5480
.then(response => {
@@ -89,4 +115,16 @@ self.addEventListener('message', event => {
89115
if (event.data && event.data.type === 'SKIP_WAITING') {
90116
self.skipWaiting();
91117
}
118+
119+
// 处理强制刷新缓存请求
120+
if (event.data && event.data.type === 'FORCE_REFRESH') {
121+
caches.delete(CACHE_NAME).then(() => {
122+
console.log('Service Worker: 缓存已清除,正在重新加载...');
123+
self.clients.matchAll().then(clients => {
124+
clients.forEach(client => {
125+
client.postMessage({ type: 'CACHE_CLEARED' });
126+
});
127+
});
128+
});
129+
}
92130
});

0 commit comments

Comments
 (0)