Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Huge freezes/lags when using automatic instrumentation with react-navigation & expo #3796

Open
4 tasks
yonitou opened this issue May 1, 2024 · 13 comments
Open
4 tasks

Comments

@yonitou
Copy link

yonitou commented May 1, 2024

Platform:

  • [X ] iOS
  • Android

SDK:

  • [ X] @sentry/react-native (>= 1.0.0)
  • react-native-sentry (<= 0.43.2)

SDK version: 5.19.1

react-native version: 0.73.4

Are you using Expo?

  • [ X] Yes
  • No

Are you using sentry.io or on-premise?

  • [ X] sentry.io (SaaS)
  • on-premise

If you are using sentry.io, please post a link to your issue so we can take a look:

Hard to send a link since it's related to freezes and slow performances

Configuration:

(@sentry/react-native)

import { createNavigationContainerRef, ParamListBase } from "@react-navigation/native";

const routingInstrumentation = new Sentry.ReactNavigationInstrumentation();

Sentry.init({
	_experiments: {
		profilesSampleRate: 0.3
	},
	attachScreenshot: true,
	beforeBreadcrumb: (breadcrumb, hint) => {
		if (breadcrumb.category !== "xhr") return breadcrumb;

		if (
			hint.xhr?.responseURL?.includes("logs") ||
			hint.xhr?.responseURL?.includes("generate_204") ||
			hint.xhr?.responseURL?.includes("symbolicate") ||
			hint.xhr?.responseURL?.includes("amplitude")
		) {
			return null;
		}

		const xhr = hint.xhr;
		const data = {
			requestBody: xhr.__sentry_xhr_v3__?.body,
			response: xhr.response,
			responseUrl: xhr.responseURL
		};
		return { ...breadcrumb, data };
	},
	beforeSend(
		event,
		hint: {
			originalException: {
				response: { data: { code: string }; request: { responseURL: string }; status: number };
			};
		}
	) {
		const status = hint.originalException?.response?.status;
		const code =
			hint.originalException?.response?.data?.code ?? (status === 502 ? "502 Bad Gateway" : "Unknown Code");
		const url = hint.originalException?.response?.request?.responseURL?.replace(/[0-9]+/g, "X");
		if (status && code && url) {
			event.fingerprint = [url, status.toString(), code];
		}
		return event;
	},
	debug: __DEV__,
	dsn: Constants.expoConfig.extra.sentryDSN,
	enabled: Constants.expoConfig.extra.appEnv !== ENV.DEVELOPMENT,
	integrations: [
		new Sentry.ReactNativeTracing({
			routingInstrumentation
		})
	],
	tracesSampleRate: 1
});

export const navigationRef = createNavigationContainerRef<ParamListBase>();

<NavigationContainer
			linking={{
				config,
				getInitialURL: async () => {
					const url = await Linking.getInitialURL();
					setDeepLink(url);
					return url;
				},
				prefixes: [schemeURL, universalLinkPrefix]
			}}
                     onReady={() => {
                       routingInstrumentation.registerNavigationContainer(navigationRef);
                   }}>
			ref={navigationRef}
		>

I have the following issue:

When I add the integration Sentry.ReactNativeTracing with the routing instrumentation for react navigation with the setup above (you will notice that my ref is not created using useRef but with createNavigationContainerRef from react-navigation because I need it for other things in my app), things start to be very slow and I'm experiencing huge freezes when navigating across my screens especially when I'm navigation through my tabs.

Actual result:

  • Experiencing multiple freezes when navigating across my screens (especially my tabs)

Expected result:

  • I should not experience any performance degradations
@krystofwoldrich
Copy link
Member

Hi @yonitou,
thank you for the message,
could you try to run the application without profiling to check if the freezes are related to profiling load or the navigation instrumentation it self.

Would you be able to reproduce this in an example app or share a link to some recorded sentry profiles for us to inspect.
You can use my email address krystof.woldrich@sentry.io or Discord if you can share the link publicly.

@yonitou
Copy link
Author

yonitou commented May 2, 2024

I tried the following :

@kahest
Copy link
Member

kahest commented May 6, 2024

Thanks for testing and the link @yonitou! We'll need to investigate and follow up here

@yonitou
Copy link
Author

yonitou commented May 6, 2024

Thanks a lot :) waiting for your feedbacks. I hope my profiling link will help.

@krystofwoldrich
Copy link
Member

krystofwoldrich commented May 10, 2024

Hi @yonitou,
sadly we do not see any suspicious calls in the profile.

To narrow down what is causing the freezes/lags, could you try to disable some of the tracing features?

new Sentry.ReactNativeTracing({
    routingInstrumentation,
    enableStallTracking: false,
})

Could you also share how you measure the freezes or do you observe them when testing the application?

@yonitou
Copy link
Author

yonitou commented May 10, 2024

Hi @krystofwoldrich
I just tried with enableStallTracking at false, it changes nothing. I made a screen recording of my app with and without the instrumentation. I'm running it on my expo development build so it's not really "smooth" but you will see a huge difference between both recordings. I've enabled the react native performance monitoring panel in the top if it can help

The first one is WITHOUT the instrumentation. You can see that it's quite smooth (the development build is never as smooth as a production one in my case) and the switch between tabs is almost instantaneous and the feedback is immediate
https://github.com/getsentry/sentry-react-native/assets/61981305/4282a661-1df3-49f9-80b5-e7ffdb8ec292

This one is WITH the instrumentation on ! Look at those freezes. You can't see it (because the screen recording doesn't show my finger taps) but when you see me waiting on a screen, it's because I'm trying to navigate through my tabs but I don't have any feedback, the app is completely stuck and then, getting unstuck at some point..
https://github.com/getsentry/sentry-react-native/assets/61981305/bbb09b1b-4416-4347-8339-3e09b7404167

Does it help ?

@krystofwoldrich
Copy link
Member

Hi @yonitou,
this is super useful for us to understand what is happening, but sadly it's it doesn't help with debugging the issue.

From the second video the JS thread is pinned to 60 FPS which is suspicious since the other video show dropping frame rate. Do you observe anything in the JS Console logs during the freeze? Is there any Sentry log just before/after the freeze? Or the console doesn't freeze?

Would you be able to reproduce this in a sample app that you could share with us, so we can debug it?

@yonitou
Copy link
Author

yonitou commented May 24, 2024

Hey
Sorry for the delay. I have maybe more "clues" to give you :

  • The first one is that everytime I'm launching my app in dev mode with sentry enabled, I've the warning
    Sentry Logger [warn]: You appear to have multiple versions of the "promise" package installed. This may cause unexpected behavior like undefinedPromise.allSettled. Please install the promise package manually using the exact version as the React Native package. See https://docs.sentry.io/platforms/react-native/troubleshooting/ for more details.
  • Next, it looks like that once I navigated once or twice on every Tab screen, the navigation is smooth again. It's like I had to navigate at least once to "register" the screen on first mount (it's at this moment that the lags I'm experiencing are happening)
  • Lastly, I tried to isolate which logs are related to the freeze. It's hard to say because a lot of logs are coming in debug mode but from what I can tell it's exactly here because the freeze is also present in my JS console.
 Sentry Logger [log]: [NativeFrames] Could not fetch native frames for navigation transaction MileosScreen. Not adding native frames measurements.
 LOG  Sentry Logger [log]: [TouchEvents] Touch event within element: Text
 LOG  Sentry Logger [log]: [ReactNativeTracing] User Interaction Tracing is disabled.
 LOG  Sentry Logger [log]: Setting idle transaction on scope. Span ID: 9652cc4888f34dc1
 LOG  Sentry Logger [log]: [Tracing] starting navigation transaction - Route Change
 LOG  Sentry Logger [log]: Starting heartbeat
 LOG  Sentry Logger [log]: pinging Heartbeat -> current counter: 0
 LOG  Sentry Logger [log]: [Profiling] Skip profiling transaction due to sampling.
 LOG  Sentry Logger [log]: [ReactNativeTracing] Starting navigation transaction "Route Change" on scope
 LOG  Sentry Logger [log]: [NativeFrames] Native frames timed out for navigation transaction MileosScreen. Not adding native frames measurements.
 LOG  Sentry Logger [log]: [Tracing] finishing IdleTransaction 2024-05-24T14:23:51.825Z navigation

Does it help ?

@krystofwoldrich
Copy link
Member

Thank you @yonitou,
based on the latest logs, it might be related to the native frames fetch.

Could you try to disable it to confirm the theory.

new Sentry.ReactNativeTracing({
    routingInstrumentation,
    enableNativeFramesTracking: false,
})

@yonitou
Copy link
Author

yonitou commented May 27, 2024

Not changing anything :/

I just made a new test to isolate the freezing logs. Here's the result :

 Sentry Logger [log]: [Profiling] Created profile 029df61546b944efaeedba61ab4eecdd for transaction 1687c8de7fec4d3e830cb9f61dc1bfa4

--------> ITS FREEZING HERE <------------

 LOG  Sentry Logger [log]: [Tracing] popActivity 91fb63bd155d2a9b
 LOG  Sentry Logger [log]: [Tracing] new activities count 0
 LOG  Sentry Logger [log]: [TouchEvents] Touch event within element: Text
 LOG  Sentry Logger [log]: [ReactNativeTracing] User Interaction Tracing is disabled.
 LOG  Sentry Logger [log]: Setting idle transaction on scope. Span ID: a055041d9ace9a45
 LOG  Sentry Logger [log]: [Tracing] starting navigation transaction - Route Change
 LOG  Sentry Logger [log]: Starting heartbeat
 LOG  Sentry Logger [log]: pinging Heartbeat -> current counter: 0
 LOG  Sentry Logger [log]: [NATIVE] Start Profiling
 LOG  Sentry Logger [log]: [Profiling] started profiling:  76ec72d0b2e543178d24014d84efec26
 LOG  Sentry Logger [log]: [ReactNativeTracing] Starting navigation transaction "Route Change" on scope
 LOG  Sentry Logger [log]: [Tracing] pushActivity: 992ea3b3f17cf3b1
 LOG  Sentry Logger [log]: [Tracing] new activities count 1

@krystofwoldrich
Copy link
Member

@yonitou Thank you for the log, this would point to the profile creation, does it consistently freeze at the same place in the logs? Where does it freeze without profiling?

When disabling profiling, remove the option profilesSampleRate, as setting it to 0 will run the profiler but not sample any profile.

@yonitou
Copy link
Author

yonitou commented May 31, 2024

Hi,

I made another test with profilesSampleRate at 0 and enableNativeFramesTracking at false : the freezes are still here but it's hard to say where it freezes in the logs.

BUT I think I understood something : if I'm waiting for the log Sentry Logger [log]: [Tracing] Finishing navigation transaction: XXXXX, and then navigating, it's working smoothly but if I navigate to a tab and then navigate really quick to another tab BEFORE the first transaction is finished, this is freezing ! Does it help ?

@krystofwoldrich
Copy link
Member

Hi,
@yonitou thank you for the details, this narrows the investigation, we will keep you updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting for: Product Owner
Status: No status
Status: Needs Investigation
Development

No branches or pull requests

3 participants