Skip to content

fix(ui): clean up window event listeners and ResizeObserver in destroy()#831

Merged
koala73 merged 1 commit intokoala73:mainfrom
NewCoder3294:fix/event-listener-memory-leaks
Mar 5, 2026
Merged

fix(ui): clean up window event listeners and ResizeObserver in destroy()#831
koala73 merged 1 commit intokoala73:mainfrom
NewCoder3294:fix/event-listener-memory-leaks

Conversation

@NewCoder3294
Copy link
Contributor

Summary

Multiple components add window-level event listeners using anonymous callbacks, making them impossible to remove when destroy() is called. This causes memory leaks as listeners accumulate across component mount/unmount cycles (e.g., when switching views or panels).

The pattern fixed in each component:

  • Anonymous callback passed to addEventListener → stored as a named class property
  • destroy() now calls removeEventListener with the same function reference

Components fixed

  • CountryTimeline.tstheme-changed listener was never removed in destroy(). Stored handler as this.handleThemeChange, added removeEventListener call in destroy().
  • DeckGLMap.tstheme-changed listener was never removed in destroy(). Same fix pattern.
  • Map.ts — Two leaks fixed:
    1. theme-changed listener was never removed in destroy(). Same fix pattern.
    2. ResizeObserver was created as a local variable inside setupResizeObserver(), so it could never be disconnected. Promoted to this.resizeObserver class property and added disconnect() call in destroy().

Note: BreakingNewsBanner.ts was also audited but already correctly stores all handler references and removes them in its destroy() method — no changes needed.

Test plan

  • Verify TypeScript compiles cleanly (tsc --noEmit — confirmed passing in CI pre-push hook)
  • Mount and destroy CountryTimeline, DeckGLMap, and Map components repeatedly; confirm no accumulating theme-changed listeners via DevTools Event Listeners panel
  • Toggle theme after component destruction; confirm no errors from stale listeners
  • Resize browser window after Map component destruction; confirm no errors from stale ResizeObserver

🤖 Generated with Claude Code

@vercel
Copy link

vercel bot commented Mar 2, 2026

@NewCoder3294 is attempting to deploy a commit to the Elie Team on Vercel.

A member of the Team first needs to authorize it.

@koala73 koala73 added Not Ready to Merge PR has conflicts, failing checks, or needs work High Value Meaningful contribution to the project labels Mar 3, 2026
Multiple components added window-level event listeners using anonymous
callbacks, making them impossible to remove later. This caused memory
leaks as listeners accumulated across component lifecycles.

- CountryTimeline: store theme-changed handler, remove in destroy()
- DeckGLMap: store theme-changed handler, remove in destroy()
- Map: store theme-changed handler, promote ResizeObserver from local
  variable to class property, disconnect and remove both in destroy()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@koala73 koala73 force-pushed the fix/event-listener-memory-leaks branch from c5493db to b530dc9 Compare March 5, 2026 07:57
@koala73 koala73 merged commit 07f552a into koala73:main Mar 5, 2026
1 check failed
aldoyh pushed a commit to aldoyh/worldmonitor that referenced this pull request Mar 6, 2026
…y() (koala73#831)

Multiple components added window-level event listeners using anonymous
callbacks, making them impossible to remove later. This caused memory
leaks as listeners accumulated across component lifecycles.

- CountryTimeline: store theme-changed handler, remove in destroy()
- DeckGLMap: store theme-changed handler, remove in destroy()
- Map: store theme-changed handler, promote ResizeObserver from local
  variable to class property, disconnect and remove both in destroy()

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

High Value Meaningful contribution to the project Not Ready to Merge PR has conflicts, failing checks, or needs work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants