From feb7afaf309386132c4f422e30d21e0082884366 Mon Sep 17 00:00:00 2001 From: zhom <2717306+zhom@users.noreply.github.com> Date: Sun, 12 Apr 2026 01:58:48 +0400 Subject: [PATCH] refactor: x64 performance --- src-tauri/src/lib.rs | 40 +++++++++++++++++++++++++++++---- src-tauri/src/sync/scheduler.rs | 2 +- src/hooks/use-permissions.ts | 8 +++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2911958..fe34e49 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1537,7 +1537,7 @@ pub fn run() { let _app_handle_cleanup = app.handle().clone(); tauri::async_runtime::spawn(async move { let camoufox_manager = crate::camoufox_manager::CamoufoxManager::instance(); - let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(5)); + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(60)); loop { interval.tick().await; @@ -1611,19 +1611,27 @@ pub fn run() { } }); - // Periodically broadcast browser running status to the frontend + // Periodically broadcast browser running status to the frontend. + // When no profiles have stored PIDs (nothing was ever launched this + // session), we use a long interval (30s) to avoid burning CPU on + // full process-table scans via sysinfo. Once any profile is running + // we switch to the fast interval (5s) for responsive UI updates. let app_handle_status = app.handle().clone(); tauri::async_runtime::spawn(async move { - let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(5)); + const FAST_INTERVAL_SECS: u64 = 5; + const IDLE_INTERVAL_SECS: u64 = 30; + + let mut interval = + tokio::time::interval(tokio::time::Duration::from_secs(FAST_INTERVAL_SECS)); interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); let mut last_running_states: std::collections::HashMap = std::collections::HashMap::new(); + let mut current_interval_secs = FAST_INTERVAL_SECS; loop { interval.tick().await; let runner = crate::browser_runner::BrowserRunner::instance(); - // If listing profiles fails, skip this tick let profiles = match runner.profile_manager.list_profiles() { Ok(p) => p, Err(e) => { @@ -1632,6 +1640,30 @@ pub fn run() { } }; + // If no profile has a stored PID and we have no previously-known + // running states, there's nothing to check — skip the expensive + // process scan entirely. + let any_has_pid = profiles.iter().any(|p| p.process_id.is_some()); + let any_was_running = last_running_states.values().any(|&v| v); + + if !any_has_pid && !any_was_running { + // Switch to the idle interval to reduce CPU + if current_interval_secs != IDLE_INTERVAL_SECS { + current_interval_secs = IDLE_INTERVAL_SECS; + interval = + tokio::time::interval(tokio::time::Duration::from_secs(IDLE_INTERVAL_SECS)); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + } + continue; + } + + // At least one profile might be running — use the fast interval + if current_interval_secs != FAST_INTERVAL_SECS { + current_interval_secs = FAST_INTERVAL_SECS; + interval = tokio::time::interval(tokio::time::Duration::from_secs(FAST_INTERVAL_SECS)); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + } + for profile in profiles { // Check browser status and track changes match runner diff --git a/src-tauri/src/sync/scheduler.rs b/src-tauri/src/sync/scheduler.rs index 9d63ecb..62be7c5 100644 --- a/src-tauri/src/sync/scheduler.rs +++ b/src-tauri/src/sync/scheduler.rs @@ -344,7 +344,7 @@ impl SyncScheduler { } } } - _ = sleep(Duration::from_millis(500)) => { + _ = sleep(Duration::from_millis(2000)) => { scheduler.process_pending(&app_handle_clone).await; } } diff --git a/src/hooks/use-permissions.ts b/src/hooks/use-permissions.ts index da156c5..9decff7 100644 --- a/src/hooks/use-permissions.ts +++ b/src/hooks/use-permissions.ts @@ -145,14 +145,18 @@ export function usePermissions(): UsePermissionsReturn { initializePlatform(); }, []); - // Set up interval checking when platform is determined + // Set up interval checking when platform is determined. + // On non-macOS platforms, permissions are always granted — a single check + // is enough and we skip the interval entirely to avoid burning CPU. useEffect(() => { if (!currentPlatform) return; // Initial check void checkPermissions(); - // Set up 500ms interval for checking permissions + // Only poll on macOS where permissions can change at runtime + if (currentPlatform !== "macos") return; + intervalRef.current = setInterval(() => { void checkPermissions(); }, 500);