[frontend] Timer leaks: 145 setTimeout/setInterval with only 42 matching clears #797

Open
opened 2026-06-03 00:42:57 +02:00 by sleepy · 0 comments
Owner

Finding

Across the largest JS files, timers are created far more often than they are cleared:

File setTimeout/setInterval clearTimeout/clearInterval Delta
chat.js 29 25 4
document.js 42 20 22
sessions.js 19 9 10
settings.js 25 3 22
notes.js 33 10 23
emailLibrary.js 26 4 22

Total: 174 timers created, only 71 cleared — 103 potentially leaked timers.

Impact

  • Orphaned intervals run forever (e.g., research polling at line 3901 runs setInterval every 2s, only cleared on specific conditions)
  • Orphaned timeouts fire on destroyed DOM elements or stale closures
  • Memory cannot be reclaimed because closures retain references to large objects
  • Particularly problematic for long-lived SPA pages where the user may be active for hours

Recommendation

  1. Track all timer IDs per module and clear them on teardown
  2. Use AbortController to cancel both fetch and timers atomically
  3. Guard all timer callbacks with DOM existence checks before acting
## Finding Across the largest JS files, timers are created far more often than they are cleared: | File | setTimeout/setInterval | clearTimeout/clearInterval | Delta | |------|----------------------|---------------------------|-------| | chat.js | 29 | 25 | 4 | | document.js | 42 | 20 | **22** | | sessions.js | 19 | 9 | **10** | | settings.js | 25 | 3 | **22** | | notes.js | 33 | 10 | **23** | | emailLibrary.js | 26 | 4 | **22** | **Total: 174 timers created, only 71 cleared — 103 potentially leaked timers.** ## Impact - Orphaned intervals run forever (e.g., research polling at line 3901 runs `setInterval` every 2s, only cleared on specific conditions) - Orphaned timeouts fire on destroyed DOM elements or stale closures - Memory cannot be reclaimed because closures retain references to large objects - Particularly problematic for long-lived SPA pages where the user may be active for hours ## Recommendation 1. Track all timer IDs per module and clear them on teardown 2. Use AbortController to cancel both fetch and timers atomically 3. Guard all timer callbacks with DOM existence checks before acting
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sleepy/odysseus#797
No description provided.