用户端缓存
浏览器通常会缓存静态资源(如JS、CSS、图片等),回滚代码后,用户可能仍会加载到缓存中的旧资源。
解决方案:
- 缓存控制:在HTTP头中设置Cache-Control和Expires,控制缓存时间。例如:
Cache-Control: no-cache, no-store, must-revalidate
- 资源版本化:在静态资源的URL中加入版本号或哈希值,每次发布新版本时,生成新的资源名称。例如:
<script src="app.js?v=1.2.3"></script>
<link rel="stylesheet" href="styles.abcdef.css">
CDN缓存
如果使用CDN分发静态资源,CDN也会缓存资源。
解决方案:
- 刷新CDN缓存:在回滚代码后,立即刷新CDN缓存,确保用户加载到最新的资源。
- CDN版本化:与用户端缓存类似,通过资源版本化避免CDN缓存旧资源。
动态资源
对于动态资源(如API接口),通常不会有缓存问题,因为这些资源每次请求都会重新获取。
解决方案:
- 确保API兼容性:在升级过程中,确保API版本的兼容性,不要影响前端正常调用。
用户长时间停留
解决方案:
- 打包时添加一个带版本信息的json,随后用Service Worker轮询json文件的版本信息,发现问题后提示用户刷新页面。
self.addEventListener('install', event => {
self.skipWaiting();
});
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim());
});
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request).catch(() => caches.match(event.request))
);
});
// 定期检查更新
setInterval(() => {
fetch('/manifest.json', { cache: 'no-cache' })
.then(response => response.json())
.then(manifest => {
const currentVersion = localStorage.getItem('appVersion');
if (manifest.version !== currentVersion) {
self.clients.matchAll().then(clients => {
clients.forEach(client => client.postMessage({ type: 'UPDATE_AVAILABLE' }));
});
}
});
}, 60000); // 每分钟检查一次
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('Service Worker registered with scope:', registration.scope);
});
navigator.serviceWorker.addEventListener('message', event => {
if (event.data.type === 'UPDATE_AVAILABLE') {
if (confirm('A new version is available. Do you want to refresh?')) {
localStorage.setItem('appVersion', new Date().toISOString());
window.location.reload();
}
}
});
}