RocketChat / RocketChat/Rocket.Chat
Livechat widget leaks event listeners and intervals on teardown / re-initialization
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
Description:
The Livechat widget does not correctly clean up event listeners, intervals, and callbacks when it is removed or re-initialized.
In widget.ts, clearAllCallbacks() incorrectly calls off() using a new function reference instead of the original registered handler, so callbacks are never actually removed. Additionally, several listeners (message listeners, media-query listeners) and intervals are created without corresponding teardown logic. removeWidget() currently removes only DOM elements and does not release these resources.
The same lifecycle cleanup gaps exist in the legacy Livechat widget bundle (rocket-livechat.js / minified version).
This causes memory and event-listener leaks when the widget is mounted and unmounted multiple times (e.g., SPA navigation, embeds, re-initialization).
Steps to reproduce:
- Embed the Livechat widget on a page.
- Initialize the widget.
- Remove the widget (or navigate away in an SPA).
- Re-initialize the widget multiple times.
- Observe growing numbers of event listeners, intervals, or callbacks via browser devtools or profiling.
Expected behavior:
All event listeners, intervals, and callbacks registered by the widget should be removed on teardown.
Re-initializing the widget should not accumulate listeners or timers.
clearAllCallbacks() should correctly unregister previously registered handlers.
Actual behavior:
Event listeners and intervals remain active after widget removal.
clearAllCallbacks() fails to unregister callbacks due to handler identity mismatch.
Re-initializing the widget causes listeners and timers to accumulate, leading to memory growth and duplicated behavior.
Server Setup Information:
- Version of Rocket.Chat Server: N/A
- License Type: N/A
- Number of Users: N/A
- Operating System: N/A
- Deployment Method: N/A
- Number of Running Instances: N/A
- DB Replicaset Oplog: N/A
- NodeJS Version: N/A
- MongoDB Version: N/A
Client Setup Information
- Desktop App or Browser Version: Any (browser-based widget)
- Operating System: Any
Additional context
This issue affects both the modern Livechat widget (widget.ts) and the legacy widget bundle.
The leak is most visible in environments where the widget is mounted/unmounted repeatedly, such as SPAs or embedded integrations.
Relevant logs:
No server logs required.
The issue can be confirmed via browser devtools by observing unreleased listeners and timers after widget teardown.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with widget.ts and trace the handlers, message and media-query listeners, intervals, and clearAllCallbacks() through removeWidget(). Compare the same lifecycle paths in rocket-livechat.js and its minified bundle, then use browser devtools while repeatedly mounting and removing the widget. Done means teardown releases all registered resources and re-initialization does not accumulate listeners, timers, or callbacks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- frontend, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100