Repository navigation
🐛 Deduplicate Next.js views across discarded mount renders - #5111
Open
BeltranBulbarellaDD wants to merge 1 commit into
Open
BeltranBulbarellaDD wants to merge 1 commit into
BeltranBulbarellaDD wants to merge 1 commit into
Conversation
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. |
|
✅ All CI checks and tests passed. 🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: b8c143f | Docs | View more details | Give us feedback! |
Bundles Sizes Evolution
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Addresses #4931: a single page load can produce hundreds of RUM views with the same URL and distinct view IDs, without any navigation.
DatadogAppRouterstarts the view during render and uses a component-localuseRefto remember the pathname. If React abandons a mount render before it commits, a retry can receive a fresh ref. The guard resets, but the previousstartView()call has already created a view.For example, a client component rendered after
DatadogAppRouterin the root layout can suspend while its JavaScript chunk loads. Without a Suspense boundary isolating that sibling, React can retry the root and start the same view on each attempt. The new E2E delays that chunk by 150 ms, reproducing the trigger described in this issue comment. Locally, the original implementation produced 253 distinct views for one load; the fix produces one.Changes
Move the last started App Router pathname into the Next.js plugin's module state, so consecutive renders of the same pathname share the guard even when React discards the component instance. Only record the pathname after RUM initialization, and clear it when the plugin resets.
Deduplication uses the concrete pathname:
/user/42→/user/99→/user/42still creates three views even though all three have the normalized name/user/[id]. View creation stays in render, preserving its current timing and initial normalized name.This fix covers consecutive retries of the same pathname. It does not prevent a view from being created for a different pathname whose render is later abandoned; that behavior was also reproduced with the original
useRefimplementation.Test instructions
Manual reproduction using the Next.js test app:
In
test/apps/nextjs/app/lazy-hydration-marker.tsx, temporarily delay the lazy import:This keeps the root layout suspended long enough for React to retry it. Keep the marker immediately after
DatadogAppRouter, without adding a Suspense boundary around it.In
test/apps/nextjs/instrumentation-client.js, replace the current code with:Build and start the production app from the repository root:
Open DevTools, turn off Preserve log, and load
http://localhost:3000/?delay-client-chunk. Wait for hydration to finish;performance.getEntriesByName('root-hydration-marker').lengthshould be1. With the fix, the console should show exactly oneRUM startViewcall for/. Repeat a full reload to check again.Checklist