Skip to content

Memory Leak: lastCapturedEvent holds a strong reference to an event that prevents DOM subtrees from being garbage collected #9204

@jblas

Description

@jblas

Is there an existing issue for this?

How do you use Sentry?

Self-hosted/on-premise

Which SDK are you using?

@sentry/react

SDK Version

7.57.0

Framework Version

React 17.0.0

Link to Sentry event

No response

SDK Setup

No response

Steps to Reproduce

  1. Click on any element on screen
  2. Observe that lastCaptureElement in instrument.ts is maintained until next click

There is some code in makeDOMEventHandler() inside instrument.ts that stores the last click/keypress event in a module global called lastCapturedEvent:

https://github.com/getsentry/sentry-javascript/blob/develop/packages/utils/src/instrument.ts#L500

for the sole purpose of preventing further processing of the same event as it propagates up through the ancestor hierarchy.

https://github.com/getsentry/sentry-javascript/blob/develop/packages/utils/src/instrument.ts#L482

We were wondering if it would be possible for this code to NOT hold a hard reference to the last event, and instead employ some other method that allows the code to figure out that the current event was already seen. Some possible alternate methods could be:

  • Tag the event the first time it is seen with a property on the event that indicates that it has already been seen/processed by the event handler and NOT maintain a lastCapturedEvent at all.
  • Have lastCapturedEvent be a WeakRef instead of a hard ref to the event in question.

Within our development workflow, we have tests that try to ensure various aspects of our UI (DOM subtrees) are released/garbage-collected after they are dismissed, usually via a click event. We noticed that when using sentry.js, these tests fail because the lastCapturedEvent reference requires a 2nd click/keypress event to remove the hard reference to the click event that dismissed the UI. The main issue here is that as long as lastCapturedEvent holds a reference to this event, its detail and target properties also hold hard references to data and the target DOM element that can prevent an entire DOM subtree from being garbage collected.

Expected Result

No hard references maintained that would impact the application's functionality or testing.

Actual Result

Within our development workflow, we have tests that try to ensure various aspects of our UI (DOM subtrees) are released/garbage-collected after they are dismissed, usually via a click event. We noticed that when using sentry.js, these tests fail because the lastCapturedEvent reference requires a 2nd click/keypress event to remove the hard reference to the click that dismissed the UI. The main issue here is that as long as lastCapturedEvent holds a reference to this event, its detail and target properties also hold hard references to data and the target DOM element that can prevent an entire DOM subtree from being garbage collected.

Metadata

Metadata

Assignees

Labels

Package: reactIssues related to the Sentry React SDK

Type

No type

Projects

Status

Waiting for: Product Owner

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions