⚗️ Add canvas change detection for Session Replay - #4949
⚗️ Add canvas change detection for Session Replay#4949BeltranBulbarellaDD wants to merge 6 commits into
Conversation
Bundles Sizes Evolution
|
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 685c28e8ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
434f477 to
ad260aa
Compare
ad260aa to
07a7e6c
Compare
3a78417 to
dc6b3d5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc6b3d5c72
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| instrumentationStoppers.push( | ||
| instrumentSetter(HTMLCanvasElement.prototype, 'width', markCanvasDirty), | ||
| instrumentSetter(HTMLCanvasElement.prototype, 'height', markCanvasDirty), | ||
| instrumentMethod(Element.prototype, 'setAttribute', ({ target, parameters, onPostCall }) => { |
There was a problem hiding this comment.
Observe every canvas size attribute mutation
issue: When an application changes width or height through another valid DOM entry point—such as canvas.toggleAttribute('width'), setAttributeNS(null, 'width', ...), or canvas.attributes.width.value = ...—the bitmap is reset without passing through either wrapper, so the canvas remains clean and replay can retain a stale frame until another tracked drawing call. Fresh evidence in the updated code is that only Element.setAttribute and Element.removeAttribute are instrumented; observing size-attribute mutations (or covering the remaining entry points) is needed.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| export function createCanvasManager(): CanvasManager { | ||
| const dirtyCanvases = new WeakSet<HTMLCanvasElement>() |
There was a problem hiding this comment.
Capture canvases that were rendered before recording starts
issue: When Session Replay starts after an application has already rendered a canvas—particularly with startSessionReplayRecordingManually—the new manager reports that canvas as clean, and the only calls to markCanvasDirty come from mutations occurring after instrumentation begins. A static chart or signature rendered before recording can therefore be omitted indefinitely because it never produces a later tracked mutation; canvases without a previously captured frame need to be treated as dirty, for example when first discovered during serialization or sampling.
Useful? React with 👍 / 👎.
Motivation
Canvas image capture can be expensive, so Session Replay should only capture a canvas after its contents have changed. This stacked PR adds the dirty-state pre-filter foundation for canvas recording.
Depends on #4947.
Design references:
Changes
WeakSet-backed canvas manager to track dirty canvases without retaining detached elements.CanvasRenderingContext2Dmethods and canvaswidth/heightchanges.This PR only adds change detection; capturing and marking canvases clean will be connected in a follow-up.
Test instructions
Checklist