🐛 Prevent duplicate Next.js RUM views from discarded renders - #4940
🐛 Prevent duplicate Next.js RUM views from discarded renders#4940BeltranBulbarellaDD wants to merge 10 commits into
Conversation
|
Bundles Sizes Evolution
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31857be6e6
ℹ️ 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".
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58fc0e9b68
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e9ab88490
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e9c6d7cfe4
ℹ️ 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".
Motivation
Fixes #4931.
DatadogAppRouterused to callstartNextjsView()while React rendered, with auseRefas its only guard. React may discard and retry an uncommitted render. Each retry gets a new ref, but the RUM side effect from the previous attempt has already escaped:The result is several RUM views with distinct IDs for one displayed page.
Moving that ref to module scope would only hide part of the symptom and would make React state global. It would still perform
startView()during render, so an abandoned render could create or rename a view for a route that never committed. React requires render to remain pure; effects run after commit. See React's rule and Synchronizing with Effects.Approach
We split view creation from view-name normalization:
nextjsPlugin.onInit()starts one view immediately, outside React.onRouterTransitionStart()before React renders. It starts the route-change view at navigation time, preserving loading timing for slow routes. This is the intended role of the Next.js hook.DatadogAppRouterusesuseEffectto callsetNextjsViewName(). This only turns a concrete path such as/user/42into/user/[id]; it does not create a view or block paint.This follows the same separation used by PostHog's App Router component: derive route state in render and publish it from
useEffect.Transition deduplication
Next.js can provide an opaque transition
event.idwhenexperimental.instrumentationClientRouterTransitionEventsis enabled. The plugin records the last ID and ignores a repeated callback for that same transition. Different IDs remain separate navigation attempts, including redirects. Next creates this ID instartRouterTransition.Sentry also starts navigation instrumentation from
onRouterTransitionStartrather than waiting for React to commit. Its deduplication is specifically for overlap between its legacy router patch and the hook, not repeated hook calls: handler, hook entry point.Tests
initial_loadview.