fix: 修复对话页面白屏 — SW 注册缺失导致缓存冲突
根因: 提交 20cdcc7 删除了 main.tsx 中的 SW 注册代码,声称 App.tsx
会调用 registerServiceWorker(),但实际未调用。旧 SW (cyrene-v1) 的
cache-first 策略拦截请求返回不兼容缓存,导致 React 白屏。
修复:
- App.tsx: 在组件挂载时调用 registerServiceWorker()
- sw.js: CACHE_NAME 升级到 cyrene-v2 强制清理旧缓存,增加 SKIP_WAITING
- main.tsx: 修正注释
This commit is contained in:
@@ -1,31 +1,43 @@
|
||||
const CACHE_NAME = 'cyrene-v1';
|
||||
const CACHE_NAME = 'cyrene-v2';
|
||||
const ASSETS_TO_CACHE = [
|
||||
'/',
|
||||
'/index.html',
|
||||
];
|
||||
|
||||
// Install: 缓存核心资源
|
||||
// Install: 缓存核心资源,立即激活
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
return cache.addAll(ASSETS_TO_CACHE);
|
||||
})
|
||||
);
|
||||
// 立即激活新 SW,不等待旧 SW 释放
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
// Activate: 清理旧缓存
|
||||
// Activate: 清理所有旧版本缓存,立即接管所有页面
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches.keys().then((keys) => {
|
||||
return Promise.all(
|
||||
keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key))
|
||||
keys.filter(key => key !== CACHE_NAME).map(key => {
|
||||
console.log('[SW] 清理旧缓存:', key);
|
||||
return caches.delete(key);
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
// 立即接管所有页面(无需刷新)
|
||||
self.clients.claim();
|
||||
});
|
||||
|
||||
// 检测新 SW 更新并通知客户端
|
||||
self.addEventListener('message', (event) => {
|
||||
if (event.data?.type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch: 缓存优先策略(对 API 请求使用网络优先)
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useChat } from '@/hooks/useChat';
|
||||
import { useSessionStore, isAdminUser } from '@/store/sessionStore';
|
||||
import { useChatStore } from '@/store/chatStore';
|
||||
import { fetchMessages } from '@/api/sessions';
|
||||
import { registerServiceWorker } from '@/hooks/usePWA';
|
||||
|
||||
/** URL Hash 工具 */
|
||||
const SESSION_HASH_PREFIX = 'session=';
|
||||
@@ -44,6 +45,12 @@ export default function App() {
|
||||
|
||||
const initializedRef = useRef(false);
|
||||
|
||||
// ========== PWA Service Worker ==========
|
||||
// 注册 Service Worker(在 main.tsx 移除内联注册后,由 App 组件负责)
|
||||
useEffect(() => {
|
||||
registerServiceWorker();
|
||||
}, []);
|
||||
|
||||
// ========== URL Hash 路由 ==========
|
||||
|
||||
/** 根据 hash 恢复或选择初始会话 */
|
||||
|
||||
@@ -3,8 +3,8 @@ import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
import './index.css';
|
||||
|
||||
// Service Worker 注册已移至 hooks/usePWA.ts 中的 registerServiceWorker(),
|
||||
// 避免重复注册导致的竞态条件。App.tsx 会在初始化时调用 registerServiceWorker()。
|
||||
// Service Worker 注册由 App.tsx 在初始化时调用 registerServiceWorker()(来自 hooks/usePWA.ts)。
|
||||
// 避免在入口文件直接注册导致的竞态条件。
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
|
||||
Reference in New Issue
Block a user