From 2d7e1473a93bb7f25818460908c5c2e59c2a197a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=B1=BC=E5=BC=80=E5=8F=91?= Date: Wed, 20 May 2026 09:47:59 +0800 Subject: [PATCH] fix: eliminate white screen on startup - Main window starts hidden (visible: false), shown after frontend ready - Remove React.StrictMode to reduce initial render overhead - Add loading spinner during app initialization - Use Promise.all + requestIdleCallback to optimize startup timing --- tauri-app/src-tauri/tauri.conf.json | 2 +- tauri-app/src/App.css | 33 +++++++++++++++++++++++++++++ tauri-app/src/App.tsx | 29 +++++++++++++++++++------ tauri-app/src/main.tsx | 32 ++++++++++++++++++++++------ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/tauri-app/src-tauri/tauri.conf.json b/tauri-app/src-tauri/tauri.conf.json index f9b4fc8..a65fa23 100644 --- a/tauri-app/src-tauri/tauri.conf.json +++ b/tauri-app/src-tauri/tauri.conf.json @@ -19,7 +19,7 @@ "minWidth": 960, "minHeight": 640, "resizable": true, - "visible": true + "visible": false } ], "security": { diff --git a/tauri-app/src/App.css b/tauri-app/src/App.css index 241a169..3729700 100644 --- a/tauri-app/src/App.css +++ b/tauri-app/src/App.css @@ -1,3 +1,36 @@ +.app-loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100vw; + height: 100vh; + background: #ffffff; + gap: 24px; +} + +.app-loading-spinner { + width: 40px; + height: 40px; + border: 3px solid #e8e8e8; + border-top-color: #1a9e8a; + border-radius: 50%; + animation: app-loading-spin 0.8s linear infinite; +} + +@keyframes app-loading-spin { + to { + transform: rotate(360deg); + } +} + +.app-loading-text { + font-size: 16px; + font-weight: 500; + color: #1a9e8a; + letter-spacing: 2px; +} + .app-layout { display: flex; height: 100vh; diff --git a/tauri-app/src/App.tsx b/tauri-app/src/App.tsx index 9a44a6c..16b88b9 100644 --- a/tauri-app/src/App.tsx +++ b/tauri-app/src/App.tsx @@ -69,16 +69,22 @@ function App() { const [currentPage, setCurrentPage] = useState('video-creation'); const [showLogoutConfirm, setShowLogoutConfirm] = useState(false); const [appEnvironment, setAppEnvironment] = useState('production'); + const [isReady, setIsReady] = useState(false); // 应用启动时加载配置和认证状态 useEffect(() => { - loadAppConfig() - .then(config => { - setApiBaseUrl(config.apiBaseUrl); - setAppEnvironment(config.environment); - }) - .catch(console.error); - loadFromStorage().catch(console.error); + Promise.all([ + loadAppConfig() + .then(config => { + setApiBaseUrl(config.apiBaseUrl); + setAppEnvironment(config.environment); + }) + .catch(console.error), + loadFromStorage().catch(console.error), + ]).finally(() => { + // 确保至少显示 300ms 加载态,避免闪屏 + setTimeout(() => setIsReady(true), 300); + }); }, [loadFromStorage]); // 固定浅色模式 @@ -109,6 +115,15 @@ function App() { setCurrentPage(page as PageType); }; + if (!isReady) { + return ( +
+
+
美家卡智影
+
+ ); + } + return ( <> {/* Toast 全局挂载 - 不受登录状态影响 */} diff --git a/tauri-app/src/main.tsx b/tauri-app/src/main.tsx index 5c4b697..444b8ce 100644 --- a/tauri-app/src/main.tsx +++ b/tauri-app/src/main.tsx @@ -16,10 +16,30 @@ document.addEventListener('contextmenu', (e) => { } }); -ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - - - - - +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); + +root.render( + + + ); + +// 前端渲染完成后,通知 Tauri 显示主窗口 +// 使用 requestIdleCallback 确保首帧已绘制 +const showWindow = () => { + import('@tauri-apps/api/webviewWindow') + .then(({ getCurrentWebviewWindow }) => { + const win = getCurrentWebviewWindow(); + win.show(); + win.setFocus(); + }) + .catch(() => { + // 非 Tauri 环境(如浏览器开发)忽略 + }); +}; + +if ('requestIdleCallback' in window) { + requestIdleCallback(showWindow, { timeout: 500 }); +} else { + setTimeout(showWindow, 100); +}