fix: resolve high CPU usage from event subscription loop and aggressive polling #394
+144
−74
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #393
WebKit.WebContentprocess consumes 60-75% CPU and 1GB+ RAM, causing severe UI lag — especially when switching back to Codex Monitor from another app.Root Cause
Three React hooks had unstable
useEffectdependency arrays, causing infinite re-registration loops and flooding the IPC bridge / backend with requests:useAppServerEvents—[handlers]dependency recreated every render → infinite subscribe/unsubscribe cycle on the event bridge.useWorkspaceRefreshOnFocus—[workspaces, ...]dependency recreated every render → re-registered focus/visibility listeners every render, and fired a burst of workspace + thread list refreshes on every focus event with no debounce.useRemoteThreadRefreshOnFocus— Same pattern as above, adding another immediate refresh on focus.When switching back to the app, all three hooks fired simultaneously, hammering the backend.
Changes
useAppServerEvents.tsuseRefto track the latest handlers, allowing the subscription effect to use an empty dependency array ([]) and remain stable across renders.handlers.references inside the effect withcurrentHandlers.from the ref.useWorkspaceRefreshOnFocus.tsuseRef+ empty dependency array to prevent listener re-registration.useRemoteThreadRefreshOnFocus.tsuseRef+ empty dependency array stabilization.useWorkspaceFiles.tsdocument.visibilityState === "hidden"(tab not visible / app minimized).Results (local build v0.7.49)