Skip to content

✨ [PANA-6283] Support incremental mutation Change records#4287

Merged
sethfowler-datadog merged 2 commits into
mainfrom
seth.fowler/PANA-6283-support-incremental-mutation-change-records
Mar 10, 2026
Merged

✨ [PANA-6283] Support incremental mutation Change records#4287
sethfowler-datadog merged 2 commits into
mainfrom
seth.fowler/PANA-6283-support-incremental-mutation-change-records

Conversation

@sethfowler-datadog
Copy link
Copy Markdown
Contributor

@sethfowler-datadog sethfowler-datadog commented Mar 5, 2026

Motivation

Change records should support incremental mutations. After quite a few stacked PRs, it's time to make it happen.

Changes

This PR adds a new serialization implementation for MutationObserver records, serializeMutationsAsChange.ts. In broads stroke, the implementation is similar to the existing serializeMutations.ts, but the output is a Change record instead of a record in the older V1 format.

I've tried to make the new code a little bit simpler than the old code. Many of the simplifications are possible because of a nice property of Change records: we never reuse old node ids. In particular, this means:

  • A new or moved node is always assigned a new node id that's greater than any existing node id. The algorithm does not need to build a data structure to track which nodes it has already serialized; it can simply compare their node id with the highest node id that existed before the current serialization operation started.
  • A removed node's id can simply be "forgotten", since we will never need it again. This means that the algorithm does not need to build a data structure to track which nodes have been removed; it can simply check whether a node currently has a node id assigned.

Because at this stage my focus is on ensuring that the Change serialization code matches the V1 serialization algorithm's output, the testing approach this PR uses is "instrument" the existing incremental mutation tests with a helper class, SerializationVerifier, that observes each serialization performed by the existing tests. When SerializationVerifier sees that a V1 serialization has occurred, it:

  1. Performs the same serialization using the Change serialization code.
  2. Converts the Change output to the older V1 format.
  3. Verifies that the two match.

For full snapshots, we check for byte-for-byte identical results. For incremental snapshots, we tolerate some small differences, which are documented in the code. These checks are quite strict, and combined with the extensive manual validation I've performed, I'm confident that Change serialization algorithm for both full and incremental snapshots is performing well.

Test instructions

  1. Check out this branch locally.
  2. Run yarn dev.
  3. Visit staging with the browser SDK extension running.
  4. Edit the config using the extension to ensure that the list of experimental feature flags includes use_incremental_change_records.
  5. Surf around a bit and use DD_RUM.getSessionReplayLink() in the console to get a link to your session.
  6. Verify that it plays back correctly. (I've already merged playback support, so you don't need to do anything special to view it.)

Unfortunately you can't just rely on the live session replay feature within the browser SDK extension, because I haven't yet updated the extension with the latest replay code. I'll update this comment when that changes.

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

@sethfowler-datadog sethfowler-datadog requested review from a team as code owners March 5, 2026 18:45
@sethfowler-datadog sethfowler-datadog force-pushed the seth.fowler/PANA-6282-add-USE_INCREMENTAL_CHANGE_RECORDS-feature-flag branch from bf48657 to d097957 Compare March 6, 2026 12:00
@sethfowler-datadog sethfowler-datadog force-pushed the seth.fowler/PANA-6283-support-incremental-mutation-change-records branch from 470d9aa to acb02ff Compare March 6, 2026 12:02
@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented Mar 6, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 174.43 KiB 174.43 KiB 0 B 0.00%
Rum Profiler 6.16 KiB 6.16 KiB 0 B 0.00%
Rum Recorder 25.24 KiB 27.46 KiB +2.22 KiB +8.78%
Logs 56.84 KiB 56.84 KiB 0 B 0.00%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 130.11 KiB 130.11 KiB 0 B 0.00%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.0055 0.0041 -25.45%
RUM - add action 0.016 0.0172 +7.50%
RUM - add error 0.0149 0.0127 -14.77%
RUM - add timing 0.0035 0.0028 -20.00%
RUM - start view 0.0166 0.0125 -24.70%
RUM - start/stop session replay recording 0.0009 0.0007 -22.22%
Logs - log message 0.0172 0.0148 -13.95%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
RUM - add global context 26.78 KiB 27.36 KiB +593 B
RUM - add action 50.84 KiB 51.80 KiB +978 B
RUM - add timing 26.36 KiB 25.62 KiB -763 B
RUM - add error 54.35 KiB 55.98 KiB +1.63 KiB
RUM - start/stop session replay recording 25.12 KiB 25.93 KiB +832 B
RUM - start view 448.58 KiB 451.82 KiB +3.24 KiB
Logs - log message 44.07 KiB 44.13 KiB +63 B

🔗 RealWorld

@datadog-datadog-prod-us1-2
Copy link
Copy Markdown

datadog-datadog-prod-us1-2 Bot commented Mar 6, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 77.51%
Overall Coverage: 77.22% (+0.50%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f7676c3 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

Base automatically changed from seth.fowler/PANA-6282-add-USE_INCREMENTAL_CHANGE_RECORDS-feature-flag to main March 6, 2026 13:21
@sethfowler-datadog sethfowler-datadog force-pushed the seth.fowler/PANA-6283-support-incremental-mutation-change-records branch from acb02ff to 973ca79 Compare March 6, 2026 13:24
Comment thread packages/rum/src/domain/record/serialization/serializeMutationsAsChange.ts Outdated
Comment thread packages/rum/src/domain/record/serialization/serializeMutationsAsChange.ts Outdated
Comment thread packages/rum/src/domain/record/serialization/serializeMutationsAsChange.ts Outdated
attributes = new Map<AttributeName, OldValue>()
attributeMutations.set(node, attributes)
}
const attributeName = mutation.attributeName!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we use a discriminated union for RumMutationRecord so we don't need ! here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We already are; RumMutationRecord is a union of RumCharacterDataMutationRecord, RumAttributesMutationRecord, and RumChildListMutationRecord, discriminated by a type field. The problem is that RumAttributesMutationRecord is wrongly defined this way:

export interface RumAttributesMutationRecord {
  type: 'attributes'
  target: Element
  oldValue: string | null
  attributeName: string | null
}

It should be defined like this:

export interface RumAttributesMutationRecord {
  type: 'attributes'
  target: Element
  oldValue: string | null
  attributeName: string
}

The file that defines these types has different CODEOWNERS, so I can't easily fix it in this PR, but I'll open a followup to fix it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@sethfowler-datadog sethfowler-datadog merged commit ea38025 into main Mar 10, 2026
21 checks passed
@sethfowler-datadog sethfowler-datadog deleted the seth.fowler/PANA-6283-support-incremental-mutation-change-records branch March 10, 2026 11:58
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants