Skip to content

Commit 1cbbe64

Browse files
antonisclaude
andauthored
fix(tracing): Guard getNewScreenTimeToDisplay behind enableTimeToInitialDisplay (#5849)
* fix(tracing): Guard getNewScreenTimeToDisplay behind enableTimeToInitialDisplay NATIVE.getNewScreenTimeToDisplay() was called on every navigation state change regardless of whether enableTimeToInitialDisplay was enabled. This native bridge call posts to the main thread and registers a Choreographer callback (Android) or CADisplayLink (iOS) to capture the next frame timestamp. On low-end devices (Fire TV, Chromecast) this is measurable overhead that the user could not avoid even after setting enableTimeToInitialDisplay: false. The dispatch-time native calls (setActiveSpanId, navigationProcessingSpan) were already correctly guarded behind the flag. This aligns the state-change-time call with the same guard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: Add changelog entry for navigation integration performance fixes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(tracing): Add performance note to enableTimeToInitialDisplay JSDoc Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c82db70 commit 1cbbe64

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
77
<!-- prettier-ignore-end -->
88
9+
## Unreleased
10+
11+
### Fixes
12+
13+
- Reduce `reactNavigationIntegration` performance overhead ([#5840](https://github.com/getsentry/sentry-react-native/pull/5840), [#5842](https://github.com/getsentry/sentry-react-native/pull/5842), [#5849](https://github.com/getsentry/sentry-react-native/pull/5849))
14+
- Fix duplicated breadcrumbs on Android ([#5841](https://github.com/getsentry/sentry-react-native/pull/5841))
15+
916
## 8.5.0
1017

1118
### Features
@@ -22,7 +29,6 @@
2229

2330
- Fix native frames measurements being dropped due to race condition ([#5813](https://github.com/getsentry/sentry-react-native/pull/5813))
2431
- Fix app start data lost when first navigation transaction is discarded ([#5833](https://github.com/getsentry/sentry-react-native/pull/5833))
25-
- Fix duplicated breadcrumbs on Android ([#5841](https://github.com/getsentry/sentry-react-native/pull/5841))
2632

2733
### Dependencies
2834

packages/core/src/js/tracing/reactnavigation.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ interface ReactNavigationIntegrationOptions {
117117
* Time to initial display measures the time it takes from
118118
* navigation dispatch to the render of the first frame of the new screen.
119119
*
120+
* Note: Enabling this adds native bridge calls on every navigation
121+
* which may cause noticeable overhead on low-end devices.
122+
*
120123
* @default false
121124
*/
122125
enableTimeToInitialDisplay: boolean;
@@ -438,7 +441,9 @@ export const reactNavigationIntegration = ({
438441
return undefined;
439442
}
440443

441-
addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());
444+
if (enableTimeToInitialDisplay) {
445+
addTimeToInitialDisplayFallback(latestNavigationSpan.spanContext().spanId, NATIVE.getNewScreenTimeToDisplay());
446+
}
442447

443448
if (previousRoute?.key === route.key) {
444449
debug.log(`[${INTEGRATION_NAME}] Navigation state changed, but route is the same as previous.`);

packages/core/test/tracing/reactnavigation.ttid.test.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,16 @@ describe('React Navigation - TTID', () => {
585585
}),
586586
);
587587
});
588+
589+
test('should not call getNewScreenTimeToDisplay when ttid is disabled', () => {
590+
jest.runOnlyPendingTimers(); // Flush app start transaction
591+
592+
mockWrapper.NATIVE.getNewScreenTimeToDisplay.mockClear();
593+
mockedNavigation.navigateToNewScreen();
594+
jest.runOnlyPendingTimers(); // Flush navigation transaction
595+
596+
expect(mockWrapper.NATIVE.getNewScreenTimeToDisplay).not.toHaveBeenCalled();
597+
});
588598
});
589599

590600
describe('ttid for preloaded/seen routes', () => {

0 commit comments

Comments
 (0)