Skip to content

Comments

⚗️ Partial view updates (experimental)#4201

Draft
mormubis wants to merge 7 commits intomainfrom
adlrb/partial-view
Draft

⚗️ Partial view updates (experimental)#4201
mormubis wants to merge 7 commits intomainfrom
adlrb/partial-view

Conversation

@mormubis
Copy link
Contributor

Motivation

Implement the "RUM Event Format Limitation" RFC (partial view updates) to reduce bandwidth by sending only changed fields in subsequent view events. When the partial_view_updates experimental feature flag is enabled, the SDK sends the first event per view.id as a full view event, and all subsequent updates as view_update events containing only changed fields.

Changes

Phase 1 — Foundation Types & Feature Flag:

  • Added PARTIAL_VIEW_UPDATES to ExperimentalFeature enum
  • Added VIEW_UPDATE to RumEventType and RawRumViewUpdateEvent interface
  • Added VIEW_UPDATE to RawRumEvent union and modifiableFieldPathsByEvent

Phase 2 — Diff Engine:

  • Created viewDiff.ts with computeViewDiff() and createViewDiffTracker()
  • Implements all RFC update strategies: MERGE, REPLACE, APPEND, DELETE
  • 21 unit tests covering all strategies and edge cases

Phase 3 — Pipeline Integration:

  • Modified viewCollection.ts to conditionally emit view or view_update
  • Protected view_update from beforeSend dismissal (same as view)
  • Added VIEW_UPDATE to domain context type mapping and feature flag assembly hook
  • Resilient degradation: diff failures fall back to full view event
  • 8 new unit tests across viewCollection, assembly, and featureFlagContext

Phase 4 — E2E Testing:

  • 6 Playwright E2E scenarios validating the complete feature
  • Tests: event flow, document_version ordering, feature flag toggle, navigation lifecycle, required fields, view end

All changes are gated behind enableExperimentalFeatures: ['partial_view_updates']. When the flag is OFF, behavior is identical to the current SDK.

Test instructions

# Unit tests
yarn test:unit

# E2E tests (requires init first)
yarn test:e2e:init
yarn test:e2e -g "partial view"

# Enable in an app
datadogRum.init({
  enableExperimentalFeatures: ['partial_view_updates'],
  // ...other config
})

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

🤖 Generated with Claude Code

@github-actions
Copy link

github-actions bot commented Feb 18, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cit-pr-commenter-54b7da
Copy link

cit-pr-commenter-54b7da bot commented Feb 18, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 169.55 KiB 172.23 KiB +2.68 KiB +1.58%
Rum Profiler 4.29 KiB 4.29 KiB 0 B 0.00%
Rum Recorder 24.71 KiB 24.71 KiB 0 B 0.00%
Logs 56.62 KiB 56.66 KiB +46 B +0.08%
Flagging 944 B 944 B 0 B 0.00%
Rum Slim 126.19 KiB 128.79 KiB +2.60 KiB +2.06%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance

Pending...

🧠 Memory Performance

Pending...

🔗 RealWorld

@datadog-datadog-prod-us1
Copy link

datadog-datadog-prod-us1 bot commented Feb 18, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 59.52%
Overall Coverage: 77.03% (-0.08%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 079b043 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

mormubis and others added 5 commits February 19, 2026 13:02
Implement Phases 1-2 of the partial view updates feature (behind
experimental feature flag). Add VIEW_UPDATE event type, RawRumViewUpdateEvent
interface, and a diff engine that computes minimal field-level diffs
between view states using MERGE, REPLACE, APPEND, and DELETE strategies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire the diff engine into viewCollection to conditionally emit view_update
events when the PARTIAL_VIEW_UPDATES feature flag is enabled. First event
per view.id is always a full view; subsequent updates emit only changed
fields. Includes batch routing, beforeSend protection, feature flag context
support, domain context types, and comprehensive unit tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Playwright E2E scenarios validating the complete partial view updates
feature: view + view_update event flow, document_version ordering, feature
flag toggle, navigation lifecycle, required field presence, and view end
events. Skip view_update format validation until schema is available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…a lands

Validation skips for view_update events will cause typecheck failures once
rum-events-format adds the view_update schema, serving as a reminder to
remove the skips and enable full validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix import ordering, unused imports, protected directory imports,
unsafe type assertions, and formatting across all changed files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mormubis and others added 2 commits February 19, 2026 16:24
Cast to the schema-generated RumEvent type so that comparing .type against
'view_update' is a TypeScript error (view_update is absent from the schema
union). The @ts-expect-error suppresses it now and will fail typecheck when
the schema lands — serving as a reminder to remove the skip.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The rum-events-format schema PR has landed, adding RumViewUpdateEvent to
the generated types. Remove the @ts-expect-error skips and runtime guards
that were blocking validation, and fix the TypeScript errors that surface
from the new schema:

- Remove view_update skip from formatValidation.ts and e2e validation.ts
- Update rumEvent.types.ts and profiling.ts with generated types
- Add view_update to developer extension event type color map
- Fix date/view.action optionality from ViewProperties shared schema type

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

if (rawRumEvent.type === 'view_update') {
return SKIPPED
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why is view_update explicitly skipped here, but not view?

view_update gets an explicit guard because these events are emitted by SDK-internal timers and observers — user code never triggers them, so handlingStack is never set on their domain context. Without this guard, they'd go through getSourceUrl() only to hit computeStackTrace({ stack: undefined }) and return SKIPPED anyway. The explicit guard makes the intent clear and short-circuits pointless work.

view events don't need the same guard because they can have a meaningful handlingStack — specifically when a user explicitly calls datadogRum.startView(), which captures the call stack. In that case getSourceUrl() can resolve a real file URL and the view event legitimately receives source code context. When no handlingStack is present (the common case), it naturally returns SKIPPED via the contextByFile.get(url) miss at the end.

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