# Frontend Architecture Audit ## Issues Identified ### 1. Excessive Polling & "Thundering Herd" Problems The frontend makes aggressive use of `setInterval` across multiple components to fetch data (e.g., `EmergencyPage`, `GossipGraph`). In some areas, these intervals interact poorly with retry logic. - **`useCommandApiStatus.js`**: Contained a critical bug where `setInterval` continued running even after the backend was marked offline, while `setTimeout` retry logic concurrently fired. This created exponential background polling, degrading browser performance and network availability. ### 2. State Leaks on Unmounted Components - **`AlertFeed.jsx`**: Inside a `setInterval` loop, a `setTimeout` was used to delay a state update. The interval was cleared on unmount, but the timeout was not, leading to React state updates on an unmounted component. ### 3. Missing Event Listener Cleanup - **`continuousPlatformService.js`**: Functions like `bindWsPollListeners` attach global `window` and `document` event listeners (e.g., `visibilitychange`, `cepheus:vision-ws-open`). Although structured as singletons, lack of explicit `removeEventListener` can cause issues during HMR or if the app's initialization cycle runs multiple times. ### 4. Direct Mutation of Global State - **`GossipGraph.jsx`**: Manual mutations of the `zustand` store variables (e.g., `faceRes[camId] = ...`) were spotted instead of using immutable updates. This can cause components relying on those specific slices of state to bypass re-renders or suffer from tearing. ## Recommendations - Consolidate polling loops into the central WebSocket (`wsVisionSingleton.js`). - Always return a cleanup function in `useEffect` that clears *all* asynchronous boundaries (`setTimeout` and `setInterval`). - Switch to structured state updaters via `zustand` actions rather than shallow copying and mutating nested store objects.