Context
Browser-agent TM userscript was causing Edge to hang during extended sessions. Root cause: aggressive DOM polling (two uncoordinated loops at 2s and 3s), accumulated timeout timers, and server-side memory leaks from orphaned state.
Fixes (v1.8.0)
- Merged polling loops: Two separate timers to single 3s tick(). Cuts DOM polling ~40%.
- Cached getPageState(): 2s TTL cache prevents redundant DOM traversal on heartbeats.
- Command timeout cleanup: Promise.race timers now cleared on completion via finally block.
- Circular console buffer: O(1) ring buffer replaces O(n) .shift() on every log entry.
- Server cleanup routines: 30s interval prunes dead tabs, expired resultWaiters (10min TTL), and orphaned command queues.
Key Decisions
- Single 3s polling interval is sufficient — SPA navigation detection latency goes from 2s to 3s, negligible for the use case.
- Heartbeat page state can be up to 2s stale (cached). Explicit getState commands still return fresh data.
- Server cleanup runs every 30s automatically, no longer depends on /health endpoint being hit.
Deployment
Deployed via SCP to VM (browser-agent directory is not a git repo). PM2 restarted. TM script hosted at pezant.ca/browser-agent.user.js for auto-update.
Open Items
- Monitor Edge stability over next few sessions
- If still hanging: consider requestIdleCallback wrapper, MutationObserver for SPA detection, or increasing POLL_MS to 5s