sentry-react-native icon indicating copy to clipboard operation
sentry-react-native copied to clipboard

feat(tracing): Add automatic tracing of time to initial display for react-navigation

Open krystofwoldrich opened this issue 1 year ago • 5 comments

:loudspeaker: Type of change

  • [ ] Bugfix
  • [x] New feature
  • [ ] Enhancement
  • [ ] Refactoring

:scroll: Description

This PR adds automatic TTID spans and measurements for React Navigation version 5 and newer. When TTID enables new navigation.processing span is added. This represents the duration from navigation dispatch to the new screen resolved in JS. This was the original minimum transaction duration.

Technical details

On iOS React Navigation uses ViewControllers to create RN Screens. We swizzle the RNSScreen view controller viewDidAppear to start listening for the next new frame. We can't start listening to the new frame when the JS layer is done with the navigation, because the next frame after that will be from the old screen/animation to the new screen.

A current limitation is that this works only for native view controller animations. Animations initiated from JS happen after the view didAppear.

On Android React Navigation creates Fragments to create RN Screens. We hook into onFragmentViewCreated where we check if the fragment is RNSScreenFragment. If that is we hook onto the event dispatcher attached to that fragment and wait for appeareEvent and then for the next rendered frame.

We can't use the JS viewApear hook as this is processed by the JS Engine asynchronously from the main application thread and might happen after (depending on the JS loop queue) the first frame of the screen is rendered.

Known limitations

  • Needs native code so it doesn't work in Expo Go
  • On iOS JS initiated animations, happen after the view controller first frame
  • There doesn't seem to be a way to hook into the View event dispatcher used by the RNScreens on iOS, so we had to use swizzling.

How to enable TTID

import * as Sentry from "@sentry/react-native";

const routingInstrumentation = new Sentry.ReactNavigationInstrumentation({
  enableTimeToInitialDisplay: true,
});

Sentry.init({
  integrations: [
    new Sentry.ReactNativeTracing({routingInstrumentation}),
  ],
});

Examples in Sentry

Example 1: https://sentry-sdks.sentry.io/discover/sentry-react-native:7432443eb31a4166be70d4b8d63b040b Screenshot 2024-02-16 at 10 40 30

Example 2: https://sentry-sdks.sentry.io/discover/sentry-react-native:4429cff3025b4ec8aa2b128f1d564459 Screenshot 2024-02-16 at 10 43 10

:bulb: Motivation and Context

:green_heart: How did you test it?

sample app, unit and integration tests

:pencil: Checklist

  • [x] I reviewed submitted code
  • [x] I added tests to verify changes
  • [x] No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled
  • [x] All tests passing
  • [x] No breaking changes

:crystal_ball: Next steps

  • [x] https://github.com/getsentry/sentry-cocoa/pull/3683
  • [x] https://github.com/getsentry/sentry-cocoa/pull/3684
  • [x] Bump sentry-cocoa, above changes will be included in 8.21.0

krystofwoldrich avatar Feb 12 '24 09:02 krystofwoldrich

Messages
:book: Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by :no_entry_sign: dangerJS against 9b833b28b9c93663d4cf8d85ea58f73b2d33d153

github-actions[bot] avatar Feb 12 '24 09:02 github-actions[bot]

Android (legacy) Performance metrics :rocket:

  Plain With Sentry Diff
Startup time 422.54 ms 449.60 ms 27.06 ms
Size 17.73 MiB 19.92 MiB 2.19 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
d197b5c9ca10ac3f729d1b3ef805328665aa0895+dirty 338.94 ms 354.87 ms 15.93 ms
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 373.24 ms 381.51 ms 8.27 ms
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 326.93 ms 330.14 ms 3.21 ms
ad6c2993f6b77abbcf4094d17dd1fa9f7742ae99 375.94 ms 382.02 ms 6.08 ms
9433f356583b99b5c970842ca1f926315bf23ba9 347.64 ms 356.22 ms 8.58 ms
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 375.20 ms 383.51 ms 8.31 ms
15c80abcaf3bedf5d6f15c0eebefc9e7c1524da1+dirty 336.27 ms 350.58 ms 14.31 ms
86d6d2c81bc42209de70f7f3b97a1fbbde04025f+dirty 332.90 ms 352.45 ms 19.55 ms
3853f4362ec819042552ffa9ed30e8f6627e60bf 329.68 ms 346.32 ms 16.64 ms
22e31b6ad7bd629bf078367aee82121c08977ded 396.48 ms 419.64 ms 23.16 ms

App size

Revision Plain With Sentry Diff
d197b5c9ca10ac3f729d1b3ef805328665aa0895+dirty 17.73 MiB 20.04 MiB 2.31 MiB
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 17.73 MiB 19.75 MiB 2.01 MiB
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 17.73 MiB 20.04 MiB 2.31 MiB
ad6c2993f6b77abbcf4094d17dd1fa9f7742ae99 17.73 MiB 19.75 MiB 2.02 MiB
9433f356583b99b5c970842ca1f926315bf23ba9 17.73 MiB 19.81 MiB 2.08 MiB
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 17.73 MiB 19.75 MiB 2.02 MiB
15c80abcaf3bedf5d6f15c0eebefc9e7c1524da1+dirty 17.73 MiB 20.04 MiB 2.31 MiB
86d6d2c81bc42209de70f7f3b97a1fbbde04025f+dirty 17.73 MiB 20.04 MiB 2.31 MiB
3853f4362ec819042552ffa9ed30e8f6627e60bf 17.73 MiB 19.81 MiB 2.08 MiB
22e31b6ad7bd629bf078367aee82121c08977ded 17.73 MiB 19.84 MiB 2.10 MiB

github-actions[bot] avatar Feb 19 '24 18:02 github-actions[bot]

iOS (legacy) Performance metrics :rocket:

  Plain With Sentry Diff
Startup time 1226.62 ms 1232.39 ms 5.77 ms
Size 2.36 MiB 2.91 MiB 561.07 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
80b2ce3d0ebe86bf1196944a2036912f6670295c+dirty 1265.92 ms 1268.60 ms 2.69 ms
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 1252.38 ms 1275.04 ms 22.66 ms
e5c9b8b6d5ce209fa4b3a77aa9de65bd590fa727+dirty 1258.57 ms 1267.32 ms 8.75 ms
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 1264.38 ms 1290.06 ms 25.68 ms
728164bd341a3b0e14876d86101c4bcca5b1f1ed+dirty 1256.10 ms 1259.08 ms 2.98 ms
3ffcddd6248046202afca78f6b9af8e3f591202c+dirty 1244.47 ms 1264.14 ms 19.67 ms
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 1247.06 ms 1274.58 ms 27.52 ms
457e29fc08e6edbebee646d095513d72728a5756+dirty 1253.94 ms 1269.18 ms 15.24 ms
12427f44d4b7746c431a369b538ec70ab2993c02+dirty 1267.15 ms 1271.30 ms 4.15 ms
25343377820b65409b646b44bc8e9bc9fbb51c8c+dirty 1225.08 ms 1230.26 ms 5.17 ms

App size

Revision Plain With Sentry Diff
80b2ce3d0ebe86bf1196944a2036912f6670295c+dirty 2.36 MiB 2.84 MiB 486.98 KiB
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 2.36 MiB 2.83 MiB 481.14 KiB
e5c9b8b6d5ce209fa4b3a77aa9de65bd590fa727+dirty 2.36 MiB 2.87 MiB 520.43 KiB
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 2.36 MiB 2.83 MiB 480.37 KiB
728164bd341a3b0e14876d86101c4bcca5b1f1ed+dirty 2.36 MiB 2.88 MiB 530.38 KiB
3ffcddd6248046202afca78f6b9af8e3f591202c+dirty 2.36 MiB 2.84 MiB 489.60 KiB
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 2.36 MiB 2.82 MiB 462.89 KiB
457e29fc08e6edbebee646d095513d72728a5756+dirty 2.36 MiB 2.87 MiB 520.67 KiB
12427f44d4b7746c431a369b538ec70ab2993c02+dirty 2.36 MiB 2.88 MiB 530.38 KiB
25343377820b65409b646b44bc8e9bc9fbb51c8c+dirty 2.36 MiB 2.88 MiB 525.47 KiB

github-actions[bot] avatar Feb 26 '24 19:02 github-actions[bot]

Android (new) Performance metrics :rocket:

  Plain With Sentry Diff
Startup time 354.04 ms 409.04 ms 55.00 ms
Size 7.15 MiB 8.20 MiB 1.05 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
d197b5c9ca10ac3f729d1b3ef805328665aa0895+dirty 258.75 ms 313.61 ms 54.86 ms
d361d3886b2303280797f653160c781700570edf+dirty 257.72 ms 318.76 ms 61.04 ms
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 259.04 ms 304.67 ms 45.63 ms
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 344.96 ms 358.92 ms 13.96 ms
9433f356583b99b5c970842ca1f926315bf23ba9+dirty 265.50 ms 336.08 ms 70.58 ms
31fcca2b37834863733f6f21677efb4b7a490aa8+dirty 366.64 ms 395.78 ms 29.14 ms
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 373.98 ms 394.08 ms 20.10 ms
575f9da84059fc88110565adb1ffc0751799bcf4+dirty 337.15 ms 370.47 ms 33.32 ms
15c80abcaf3bedf5d6f15c0eebefc9e7c1524da1+dirty 276.38 ms 327.54 ms 51.17 ms
86d6d2c81bc42209de70f7f3b97a1fbbde04025f+dirty 267.21 ms 325.24 ms 58.04 ms

App size

Revision Plain With Sentry Diff
d197b5c9ca10ac3f729d1b3ef805328665aa0895+dirty 7.15 MiB 8.09 MiB 962.72 KiB
d361d3886b2303280797f653160c781700570edf+dirty 7.15 MiB 8.08 MiB 959.34 KiB
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 7.15 MiB 8.03 MiB 903.20 KiB
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 7.15 MiB 8.09 MiB 962.83 KiB
9433f356583b99b5c970842ca1f926315bf23ba9+dirty 7.15 MiB 8.08 MiB 959.34 KiB
31fcca2b37834863733f6f21677efb4b7a490aa8+dirty 7.15 MiB 8.18 MiB 1.03 MiB
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 7.15 MiB 8.04 MiB 910.85 KiB
575f9da84059fc88110565adb1ffc0751799bcf4+dirty 7.15 MiB 8.10 MiB 979.68 KiB
15c80abcaf3bedf5d6f15c0eebefc9e7c1524da1+dirty 7.15 MiB 8.09 MiB 966.13 KiB
86d6d2c81bc42209de70f7f3b97a1fbbde04025f+dirty 7.15 MiB 8.09 MiB 962.69 KiB

github-actions[bot] avatar Feb 26 '24 20:02 github-actions[bot]

iOS (new) Performance metrics :rocket:

  Plain With Sentry Diff
Startup time 1216.27 ms 1217.92 ms 1.65 ms
Size 2.92 MiB 3.48 MiB 573.21 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
80b2ce3d0ebe86bf1196944a2036912f6670295c+dirty 1245.12 ms 1262.04 ms 16.92 ms
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 1288.10 ms 1289.54 ms 1.44 ms
e5c9b8b6d5ce209fa4b3a77aa9de65bd590fa727+dirty 1276.90 ms 1280.92 ms 4.02 ms
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 1271.12 ms 1272.28 ms 1.16 ms
728164bd341a3b0e14876d86101c4bcca5b1f1ed+dirty 1280.06 ms 1285.26 ms 5.20 ms
3ffcddd6248046202afca78f6b9af8e3f591202c+dirty 1272.22 ms 1273.98 ms 1.76 ms
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 1276.40 ms 1279.14 ms 2.74 ms
457e29fc08e6edbebee646d095513d72728a5756+dirty 1256.71 ms 1258.50 ms 1.79 ms
12427f44d4b7746c431a369b538ec70ab2993c02+dirty 1224.90 ms 1231.40 ms 6.50 ms
25343377820b65409b646b44bc8e9bc9fbb51c8c+dirty 1220.87 ms 1221.47 ms 0.60 ms

App size

Revision Plain With Sentry Diff
80b2ce3d0ebe86bf1196944a2036912f6670295c+dirty 2.92 MiB 3.40 MiB 492.75 KiB
d7401ac44acf524fe4d9a6a525f2cc13c70ce9e5+dirty 2.92 MiB 3.40 MiB 488.06 KiB
e5c9b8b6d5ce209fa4b3a77aa9de65bd590fa727+dirty 2.92 MiB 3.43 MiB 524.50 KiB
acadc0f974a0c234a3d9010117b076792d14d6e8+dirty 2.92 MiB 3.39 MiB 487.34 KiB
728164bd341a3b0e14876d86101c4bcca5b1f1ed+dirty 2.92 MiB 3.44 MiB 533.26 KiB
3ffcddd6248046202afca78f6b9af8e3f591202c+dirty 2.92 MiB 3.40 MiB 494.39 KiB
9a3ca655542f9224aa21b4838b439748a3043b4b+dirty 2.92 MiB 3.37 MiB 464.32 KiB
457e29fc08e6edbebee646d095513d72728a5756+dirty 2.92 MiB 3.43 MiB 524.75 KiB
12427f44d4b7746c431a369b538ec70ab2993c02+dirty 2.92 MiB 3.44 MiB 533.29 KiB
25343377820b65409b646b44bc8e9bc9fbb51c8c+dirty 2.92 MiB 3.43 MiB 529.76 KiB

github-actions[bot] avatar Feb 26 '24 20:02 github-actions[bot]