Skip to content

⚗️ Add canvas change detection for Session Replay - #4949

Open
BeltranBulbarellaDD wants to merge 6 commits into
mainfrom
beltran.bulbarella/canvas_support-2-prefilter
Open

⚗️ Add canvas change detection for Session Replay#4949
BeltranBulbarellaDD wants to merge 6 commits into
mainfrom
beltran.bulbarella/canvas_support-2-prefilter

Conversation

@BeltranBulbarellaDD

@BeltranBulbarellaDD BeltranBulbarellaDD commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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

  • Add a WeakSet-backed canvas manager to track dirty canvases without retaining detached elements.
  • Instrument bitmap-mutating CanvasRenderingContext2D methods and canvas width/height changes.
  • Enable canvas mutation tracking only when canvas recording is enabled with a positive maximum frame rate.
  • Safely handle canvas APIs that are unavailable in older browser versions.
  • Add focused unit coverage for dirty-state management, canvas instrumentation, cleanup, and recorder activation.

This PR only adds change detection; capturing and marking canvases clean will be connected in a follow-up.

Test instructions

yarn test:unit --spec packages/browser-rum/src/domain/record/canvas/canvasManager.spec.ts --spec packages/browser-rum/src/domain/record/trackers/trackCanvas.spec.ts --spec packages/browser-rum/src/domain/record/record.spec.ts
yarn typecheck

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 14, 2026

Copy link
Copy Markdown

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 181.27 KiB 181.27 KiB 0 B 0.00%
Rum Profiler 8.43 KiB 8.43 KiB 0 B 0.00%
Rum Recorder 21.12 KiB 22.25 KiB +1.12 KiB +5.32% ⚠️
Logs 57.50 KiB 57.50 KiB 0 B 0.00%
Rum Salesforce N/A 139.22 KiB N/A N/A N/A
Rum Slim 139.21 KiB 139.21 KiB 0 B 0.00%
Worker 22.96 KiB 22.96 KiB 0 B 0.00%
Rum Shopify N/A 202.14 KiB N/A N/A N/A
Rum-shopify Profiler N/A 8.43 KiB N/A N/A N/A
Rum-shopify Recorder N/A 3.72 KiB N/A N/A N/A

⚠️ The increase is particularly high and exceeds 5.00%. Please check the changes.

@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Aug 14, 2026

Copy link
Copy Markdown

Pipelines  Tests

⚠️ Warnings

🚦 1 Pipeline job failed

DataDog/browser-sdk | unit-bs: [safari-desktop]   View in Datadog   GitLab

🧪 4 Tests failed

startRecording flushes pending mutations before ending the view, even after the segment has been flushed from Safari 14.1.2 (Mac OS 10.15.7)   View in Datadog
Unexpected console call: error: 'Datadog Browser SDK:', 'Session Replay failed to start: a timeout occurred while initializing the Worker'
startRecording restarts sending segments when the session is renewed from Safari 14.1.2 (Mac OS 10.15.7)   View in Datadog
Unexpected console call: error: 'Datadog Browser SDK:', 'Session Replay failed to start: a timeout occurred while initializing the Worker'
View all failed tests

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 87.50%
Overall Coverage: 77.25% (+0.03%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: dc6b3d5 | Docs | Datadog PR Page | Give us feedback!

@BeltranBulbarellaDD BeltranBulbarellaDD changed the title Beltran.bulbarella/canvas support 2 prefilter ⚗️ Add canvas change detection for Session Replay Aug 14, 2026
@BeltranBulbarellaDD

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread packages/browser-rum/src/domain/record/trackers/trackCanvas.ts Outdated
@BeltranBulbarellaDD
BeltranBulbarellaDD force-pushed the beltran.bulbarella/canvas_support-2-prefilter branch from 434f477 to ad260aa Compare August 14, 2026 14:53
@BeltranBulbarellaDD
BeltranBulbarellaDD force-pushed the beltran.bulbarella/canvas_support-2-prefilter branch from ad260aa to 07a7e6c Compare August 17, 2026 09:19
Base automatically changed from beltran.bulbarella/canvas_support_1-initconfig to main August 17, 2026 09:38
@BeltranBulbarellaDD
BeltranBulbarellaDD force-pushed the beltran.bulbarella/canvas_support-2-prefilter branch from 3a78417 to dc6b3d5 Compare August 17, 2026 09:38
@BeltranBulbarellaDD
BeltranBulbarellaDD marked this pull request as ready for review August 17, 2026 09:40
@BeltranBulbarellaDD
BeltranBulbarellaDD requested review from a team as code owners August 17, 2026 09:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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 }) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

Comment thread packages/browser-rum/src/domain/record/trackers/trackCanvas.ts
}

export function createCanvasManager(): CanvasManager {
const dirtyCanvases = new WeakSet<HTMLCanvasElement>()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

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.

1 participant