Skip to content

Conversation

@andreiborza
Copy link
Member

Replays of apps that use canvas elements that are resumed after a long period of inactivity (for example when navigating away and back to a tab after 5 minutes) were previously broken.

Replays contained all DOM elements, including the canvas, but the canvas would not have any of its rendering captured.

This happens because before resuming from inactivity, getCanvasManager creates a new CanvasManager that is then passed to a promise resolve function that was already resolved beforehand. That leads to the new canvas manager not actually being used when returning from inactivity and thus having all rendering attempted to be captured from the previous canvas manager instead of the new one.

For backwards compatibility, I kept the promise based approach around and added a second storage variable for the canvas manager.

I attempted to create integration tests but was not able to reproduce this issue in an integration test so I opted for just a basic unit test.

I did reproduce this issue in a sample app locally and captured two replays:

  1. The first replay uses our CDN bundles and shows canvas rendering captured at first but missing towards the end of the replay.

  2. The second replay uses bundles built from this PR and shows canvas rendering continues towards the end of the replay.

Closes: #18682

inactivity

Replays of apps that use canvas elements that are resumed after a long period
of inactivity (for example when navigating away and back to a tab after 5
minutes) were previously broken.

Replays contained all DOM elements, including the canvas, but the canvas would
not have any of its rendering captured.

This happens because before resuming from inactivity, `getCanvasManager` creates
a new `CanvasManager` that is then passed to a promise resolve function that was
already resolved beforehand. That leads to the new canvas manager not actually
being used when returning from inactivity and thus having all rendering
attempted to be captured from the previous canvas manager instead of the new
one.

For backwards compatibility, I kept the promise based approach around and added
a second storage variable for the canvas manager.

I attempted to create integration tests but was not able to reproduce this issue
in an integration test so I opted for just a basic unit test.

I did reproduce this issue in a sample app locally and captured two replays:

1) The [first
replay](https://sentry-sdks.sentry.io/explore/replays/26cd46702dc448148c0c887edaa10aec/?playlistEnd=2026-01-07T13%3A05%3A52&playlistStart=2026-01-07T12%3A05%3A52&project=4507937458552832&query=&referrer=replayList) uses our CDN bundles and shows canvas rendering captured at
first but missing towards the end of the replay.

2) The [second
replay](https://sentry-sdks.sentry.io/explore/replays/765c4b98474242b0a0e690e16b59ab7f/?playlistEnd=2026-01-07T13%3A13%3A23&playlistStart=2026-01-07T12%3A13%3A23&project=4507937458552832&query=&referrer=replayList) uses bundles built from this PR and shows canvas rendering
continues towards the end of the replay.

Closes: #18682
@andreiborza andreiborza requested a review from a team as a code owner January 7, 2026 13:39
Copy link
Member

@billyvg billyvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@andreiborza andreiborza merged commit 0d0fd78 into develop Jan 7, 2026
161 checks passed
@andreiborza andreiborza deleted the ab/canvas-manager-replay-fix branch January 7, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replay does not include canvas after 5 minutes of inactivity

3 participants