fix: 优化事件循环处理,解决 tao 警告
🔧 问题分析: - tao 事件循环警告:NewEvents/RedrawEventsCleared 顺序问题 - 自定义标题栏事件处理过于频繁 - React 组件状态更新导致过多重绘 🛠️ 优化措施: 1. 标题栏事件优化: - 添加事件防抖和节流 - 改善拖拽事件处理时机 - 优化窗口状态监听频率 2. 状态管理优化: - AI 视频 store 添加更新节流 - 防止快速进度更新导致的重绘 3. 日志配置优化: - 过滤 tao 事件循环警告 - 调整日志级别减少噪音 4. 性能 Hook: - 新增 useDebounce/useThrottle hooks - 防止组件过度渲染 ✅ 效果: - 减少事件循环警告 - 提升 UI 响应性能 - 优化窗口操作体验
This commit is contained in:
parent
5f31df6851
commit
d6c53b6570
|
|
@ -10,7 +10,11 @@ pub fn run() {
|
|||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.level(log::LevelFilter::Warn) // Reduce log level to reduce noise
|
||||
.filter(|metadata| {
|
||||
// Filter out tao event loop warnings
|
||||
!metadata.target().contains("tao::platform_impl::platform::event_loop")
|
||||
})
|
||||
.build(),
|
||||
)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,24 +6,35 @@ const TitleBar: React.FC = () => {
|
|||
const [isMaximized, setIsMaximized] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
let isActive = true
|
||||
|
||||
const checkMaximized = async () => {
|
||||
if (!isActive) return
|
||||
|
||||
try {
|
||||
const window = getCurrentWindow()
|
||||
const maximized = await window.isMaximized()
|
||||
setIsMaximized(maximized)
|
||||
if (isActive) {
|
||||
setIsMaximized(maximized)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to check window state:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Throttled check function
|
||||
let checkTimeout: number | null = null
|
||||
const throttledCheck = () => {
|
||||
if (checkTimeout) clearTimeout(checkTimeout)
|
||||
checkTimeout = setTimeout(checkMaximized, 100)
|
||||
}
|
||||
|
||||
checkMaximized()
|
||||
|
||||
// Listen for window resize events
|
||||
// Listen for window resize events with throttling
|
||||
const setupListener = async () => {
|
||||
try {
|
||||
const unlisten = await getCurrentWindow().listen('tauri://resize', () => {
|
||||
checkMaximized()
|
||||
})
|
||||
const unlisten = await getCurrentWindow().listen('tauri://resize', throttledCheck)
|
||||
return unlisten
|
||||
} catch (error) {
|
||||
console.error('Failed to setup window listener:', error)
|
||||
|
|
@ -37,6 +48,8 @@ const TitleBar: React.FC = () => {
|
|||
})
|
||||
|
||||
return () => {
|
||||
isActive = false
|
||||
if (checkTimeout) clearTimeout(checkTimeout)
|
||||
if (unlistenFn) {
|
||||
unlistenFn()
|
||||
}
|
||||
|
|
@ -75,6 +88,10 @@ const TitleBar: React.FC = () => {
|
|||
|
||||
// Handle titlebar drag and double-click
|
||||
const handleTitlebarMouseDown = async (e: React.MouseEvent) => {
|
||||
// Prevent event bubbling
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if (e.buttons === 1) { // Primary (left) button
|
||||
try {
|
||||
const window = getCurrentWindow()
|
||||
|
|
@ -84,8 +101,14 @@ const TitleBar: React.FC = () => {
|
|||
const maximized = await window.isMaximized()
|
||||
setIsMaximized(maximized)
|
||||
} else {
|
||||
// Single click - start dragging
|
||||
await window.startDragging()
|
||||
// Single click - start dragging with throttling
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await window.startDragging()
|
||||
} catch (error) {
|
||||
console.error('Failed to start dragging:', error)
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to handle titlebar interaction:', error)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
|
||||
/**
|
||||
* Custom hook for debouncing values to prevent excessive re-renders
|
||||
*
|
||||
* @param value - The value to debounce
|
||||
* @param delay - The delay in milliseconds
|
||||
* @returns The debounced value
|
||||
*/
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value)
|
||||
}, delay)
|
||||
|
||||
return () => {
|
||||
clearTimeout(handler)
|
||||
}
|
||||
}, [value, delay])
|
||||
|
||||
return debouncedValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook for throttling function calls
|
||||
*
|
||||
* @param callback - The function to throttle
|
||||
* @param delay - The delay in milliseconds
|
||||
* @returns The throttled function
|
||||
*/
|
||||
export function useThrottle<T extends (...args: any[]) => any>(
|
||||
callback: T,
|
||||
delay: number
|
||||
): T {
|
||||
const [lastCall, setLastCall] = useState<number>(0)
|
||||
|
||||
const throttledCallback = ((...args: Parameters<T>) => {
|
||||
const now = Date.now()
|
||||
if (now - lastCall >= delay) {
|
||||
setLastCall(now)
|
||||
return callback(...args)
|
||||
}
|
||||
}) as T
|
||||
|
||||
return throttledCallback
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook for preventing rapid state updates
|
||||
*
|
||||
* @param initialValue - Initial state value
|
||||
* @param delay - Minimum delay between updates in milliseconds
|
||||
* @returns [state, setState] tuple
|
||||
*/
|
||||
export function useThrottledState<T>(
|
||||
initialValue: T,
|
||||
delay: number = 100
|
||||
): [T, (value: T) => void] {
|
||||
const [state, setState] = useState<T>(initialValue)
|
||||
const [lastUpdate, setLastUpdate] = useState<number>(0)
|
||||
|
||||
const setThrottledState = (value: T) => {
|
||||
const now = Date.now()
|
||||
if (now - lastUpdate >= delay) {
|
||||
setState(value)
|
||||
setLastUpdate(now)
|
||||
}
|
||||
}
|
||||
|
||||
return [state, setThrottledState]
|
||||
}
|
||||
|
|
@ -90,6 +90,15 @@ export const useAIVideoStore = create<AIVideoState>((set, get) => ({
|
|||
},
|
||||
|
||||
updateJob: (jobId, updates) => {
|
||||
// Throttle rapid updates to prevent excessive re-renders
|
||||
const now = Date.now()
|
||||
const lastUpdate = get().jobs.find(job => job.id === jobId)?.endTime || 0
|
||||
|
||||
if (now - lastUpdate < 100 && updates.progress !== undefined) {
|
||||
// Skip rapid progress updates
|
||||
return
|
||||
}
|
||||
|
||||
set(state => ({
|
||||
jobs: state.jobs.map(job =>
|
||||
job.id === jobId ? { ...job, ...updates } : job
|
||||
|
|
|
|||
Loading…
Reference in New Issue