fix(browser): Ignore React 19.2+ component render measure entries #17905
+93 −1
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.
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 fromPerformanceMeasure
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'sname
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