Skip to content

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Oct 10, 2025

This PR fixes a performance overhead regression that would emerge when using any browserTracingIntegration in an React 19.2+ app that is running in dev mode or a React Profiler build.

With 19.2, React introduced custom perfomance tracks in chrome dev tools. This track is populated by collecting performance.measure entries for every component (re-)render. Sounds good in theory but in reality this causes a massive performance degradation when using the Sentry SDK because we collect spans from PerformanceMeasure entries. In our Sentry UI, this caused 10+ second long blocks because we created thousands of spans from these render entries.

This PR fixes this performance drop by inspecting the measure entries' detail object which we can use to fairly well distinguish React's entries from users' entries. Not 100% bulletproof but I think good enough.

Alternatives Considered

Can't we just filter them out by name?

Unfortunately, we cannot filter them by name via the ignorePerformanceApiSpans option because React simply uses the component name (+ a few static strings in some occasions) for the entry's name property. I briefly tried hacking this in by relying on the \u200b (empty space character) that React prefixes the entries with. However, the static strings don't have the same prefix, so we can't get them all with this. Also, the prefix was only added to work around a Chrome DevTools bug, which at some point will get released. In which case, React could just drop the prefixes all together.

^ Didn't think I'd dive into the React code base today but well ... here we are 😅

Aren't these entries useful?

Well maybe. The thing is, they're only emitted in dev mode, so pretty useless for default prod builds. These entries will be emitted when wrapping a <Profiler> component around the sub tree but here my React knowledge isn't enough to know if people do this in prod. We can definitely revisit excluding all entries, e.g. in favour of an allowlist for which components should be tracked. For now, I'd like to avoid slowing down anyone's app by default.

closes #17888

Copy link
Contributor

github-actions bot commented Oct 10, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.4 kB - -
@sentry/browser - with treeshaking flags 22.9 kB - -
@sentry/browser (incl. Tracing) 40.67 kB +0.13% +52 B 🔺
@sentry/browser (incl. Tracing, Replay) 79.03 kB +0.06% +46 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 68.67 kB +0.07% +44 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 83.71 kB +0.06% +46 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 95.87 kB +0.06% +52 B 🔺
@sentry/browser (incl. Feedback) 41.1 kB +0.01% +1 B 🔺
@sentry/browser (incl. sendFeedback) 29.06 kB - -
@sentry/browser (incl. FeedbackAsync) 33.97 kB - -
@sentry/react 26.11 kB - -
@sentry/react (incl. Tracing) 42.6 kB +0.12% +50 B 🔺
@sentry/vue 28.92 kB - -
@sentry/vue (incl. Tracing) 42.44 kB +0.12% +50 B 🔺
@sentry/svelte 24.44 kB - -
CDN Bundle 26.63 kB - -
CDN Bundle (incl. Tracing) 41.2 kB +0.14% +54 B 🔺
CDN Bundle (incl. Tracing, Replay) 77.49 kB +0.06% +46 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 82.95 kB +0.07% +50 B 🔺
CDN Bundle - uncompressed 78.18 kB - -
CDN Bundle (incl. Tracing) - uncompressed 122.3 kB +0.1% +121 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 237.46 kB +0.06% +121 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 250.22 kB +0.05% +121 B 🔺
@sentry/nextjs (client) 44.63 kB +0.12% +51 B 🔺
@sentry/sveltekit (client) 41.03 kB +0.14% +55 B 🔺
@sentry/node-core 50.74 kB - -
@sentry/node 154.39 kB +0.02% +25 B 🔺
@sentry/node - without tracing 92.59 kB -0.01% -1 B 🔽
@sentry/aws-serverless 106.32 kB - -

View base workflow run

@Lms24 Lms24 self-assigned this Oct 10, 2025
@Lms24 Lms24 requested review from a team, AbhiPrasad, s1gr1d and stephanie-anderson and removed request for a team and stephanie-anderson October 10, 2025 10:13
if (entry?.entryType !== 'measure') {
return;
}
try {
Copy link
Member Author

Choose a reason for hiding this comment

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

using the try/catch block here because bundle size-wise, it's cheaper than relying on countless type checks to safely access the track name

@Lms24 Lms24 changed the title fix(react): Ignore React 19.2+ component render measure entries fix(browser): Ignore React 19.2+ component render measure entries Oct 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant