fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(react): Support lazy-loaded routes and components. - #15039

Merged
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages
Jan 23, 2025
Merged

fix(react): Support lazy-loaded routes and components.#15039
s1gr1d merged 3 commits into
developfrom
onur/rr-lazy-loaded-pages

Conversation

@onurtemizkan

@onurtemizkanonurtemizkan commented Jan 16, 2025

Copy link
Copy Markdown
Contributor

Fixes: #15027

This PR adds support for lazily loaded components and routes inside Suspend on react-router pageloads / navigations.

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded pages on navigationfix(react): Wait for lazy-loaded components on navigationJan 16, 2025
},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No strong feelings, this is also fine, but could we possibly add this to an existing e2e test app? Would save a little but of ci/processing time 😅

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

version,
basename,
// Use requestAnimationFrame to wait for Suspense boundaries to settle
requestAnimationFrame(() => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will slightly skew all timestamps, even if there is no suspense etc. happening, right? As this will realistically add ~20ms or so before handleNavigation() is called.

Not a blocker IMHO, but something to consider. Can we make this smarter (e.g. know when this is lazy?) somehow, possibly...?

version,
basename,
});
}, 100);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

100ms delay seems quite a lot, this will skew stuff pretty considerably, I guess 😬 does that not add 100ms to every navigation duration etc...?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we could maybe look into other fields of the RouterState https://github.com/remix-run/react-router/blob/d0e474cf6c521881044c445b4730c1a43aa77679/packages/react-router/lib/router/router.ts#L276

E.g. call handleNavigation when state.navigation !== 'loading'?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Yes, updated with the navigation state checker 👍 I also realized that putting the manual timeout made us lose the inner resource.

@codecov

codecovBot commented Jan 17, 2025

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completedFailedPassedSkipped
6891688299
View the full list of 1 ❄️ flaky tests
tracing/request/fetch/test.tsshouldcreatespansforfetchrequests

Flake rate in main: 14.29% (Passed 54 times, Failed 9 times)

Stack Traces | 10.1s run time
test.ts:7:11shouldcreatespansforfetchrequests

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

});
// Wait for the next render if loading an unsettled route
if (state.navigation.state !== 'idle') {
requestAnimationFrame(() => {

@s1gr1ds1gr1dJan 17, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, my idea with requestAnimationFrame actually worked - that's nice ✨
Thanks for implementing 🙌

But as Francesco pointed out - we should keep in mind the slight overhead and maybe there's even another way to implement this 🤔 Do we know if a route is lazy?

},
{
element: (
<Suspense fallback={<div>Loading...</div>}>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could add this to react-create-browser-router :)

@github-actions

github-actionsBot commented Jan 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser22.98 KB--
@sentry/browser - with treeshaking flags21.64 KB--
@sentry/browser (incl. Tracing)35.68 KB--
@sentry/browser (incl. Tracing, Replay)72.47 KB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags62.98 KB--
@sentry/browser (incl. Tracing, Replay with Canvas)76.72 KB--
@sentry/browser (incl. Tracing, Replay, Feedback)88.74 KB--
@sentry/browser (incl. Feedback)39.2 KB--
@sentry/browser (incl. sendFeedback)27.61 KB--
@sentry/browser (incl. FeedbackAsync)32.37 KB--
@sentry/react25.66 KB--
@sentry/react (incl. Tracing)38.46 KB+0.02%+6 B 🔺
@sentry/vue27.04 KB--
@sentry/vue (incl. Tracing)37.43 KB--
@sentry/svelte23.11 KB--
CDN Bundle24.36 KB--
CDN Bundle (incl. Tracing)36 KB--
CDN Bundle (incl. Tracing, Replay)70.65 KB--
CDN Bundle (incl. Tracing, Replay, Feedback)75.79 KB--
CDN Bundle - uncompressed71.16 KB--
CDN Bundle (incl. Tracing) - uncompressed106.82 KB--
CDN Bundle (incl. Tracing, Replay) - uncompressed217.67 KB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed230.21 KB--
@sentry/nextjs (client)38.58 KB--
@sentry/sveltekit (client)36.21 KB--
@sentry/node161.33 KB--
@sentry/node - without tracing97.15 KB--
@sentry/aws-serverless111.45 KB--

View base workflow run

@onurtemizkan
onurtemizkanforce-pushed the onur/rr-lazy-loaded-pages branch from ea60f3a to 2a8888dCompareJanuary 20, 2025 16:46
@onurtemizkan

Copy link
Copy Markdown
ContributorAuthor

@mydea, @s1gr1d, @chargome - I updated the PR to cover the lazy-loaded Routes too. So the problem was the cross-usage of wrapCreateBrowser and withSentryReactRouterRouting. We were losing the allRoutes context in one another and that was why we were not creating the full parameterized span name.

We're actually updating pageload spans and handling navigations on their render, so we can expect the lazy loading to be finished when we do them.

Still, I think we can keep requestAnimationFrame for non-idle router states when we do it as a secondary safety net. But interestingly, I can't reproduce a case with a non-idle state anymore. Looking at the RR source code, it seems possible.

@s1gr1ds1gr1d left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good from my side

@onurtemizkanonurtemizkan changed the title fix(react): Wait for lazy-loaded components on navigationfix(react): Support lazy-loaded routes and components.Jan 21, 2025

@mydeamydea left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, this looks neat - great work!

@s1gr1d
s1gr1d merged commit b49c1cc into developJan 23, 2025
@s1gr1d
s1gr1d deleted the onur/rr-lazy-loaded-pages branch January 23, 2025 08:43
onurtemizkan added a commit that referenced this pull request Feb 3, 2025
Fixes: #15027
This PR adds support for lazily loaded components and routes inside
`Suspend` on react-router pageloads / navigations.
s1gr1d pushed a commit that referenced this pull request Feb 11, 2025
Backports #15039 to v8 branch
Potentially fixes as it also fixes cross-usage of `createBrowserRouter`
and `useRoutes`: #15279
Sign up for freeto 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.

React Router browser tracing - Lazy imported routes with suspense start transaction spans with wrong path

4 participants

@onurtemizkan@mydea@chargome@s1gr1d