From 55a46c4562b7bbf2ff111cacc407fc640aa10918 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 7 May 2025 11:13:17 +0300 Subject: [PATCH 1/4] ref(session-replay): iOS: Use enableViewRendererV2 instead of the deprecated enableExperimentalViewRenderer --- .../RNSentryReplayOptionsTests.swift | 24 +++++++------- packages/core/ios/RNSentryReplay.mm | 3 +- packages/core/src/js/replay/mobilereplay.ts | 32 +++++++++++++++++-- samples/react-native/src/App.tsx | 2 +- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift index 4d94dba446..91895d0e04 100644 --- a/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift +++ b/packages/core/RNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryReplayOptionsTests.swift @@ -55,7 +55,7 @@ final class RNSentryReplayOptions: XCTestCase { XCTAssertNotNil(replayOptions["maskAllText"]) XCTAssertNotNil(replayOptions["maskedViewClasses"]) XCTAssertNotNil(replayOptions["sdkInfo"]) - XCTAssertNotNil(replayOptions["enableExperimentalViewRenderer"]) + XCTAssertNotNil(replayOptions["enableViewRendererV2"]) XCTAssertNotNil(replayOptions["enableFastViewRendering"]) } @@ -166,8 +166,8 @@ final class RNSentryReplayOptions: XCTestCase { XCTAssertEqual(actualOptions.sessionReplay.maskAllText, false) XCTAssertEqual(actualOptions.sessionReplay.maskedViewClasses.count, 0) } - - func testEnableExperimentalViewRendererDefault() { + + func testEnableViewRendererV2Default() { let optionsDict = ([ "dsn": "https://abc@def.ingest.sentry.io/1234567", "replaysOnErrorSampleRate": 0.75 @@ -177,35 +177,35 @@ final class RNSentryReplayOptions: XCTestCase { let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - XCTAssertFalse(actualOptions.sessionReplay.enableExperimentalViewRenderer) + XCTAssertTrue(actualOptions.sessionReplay.enableViewRendererV2) } - - func testEnableExperimentalViewRendererTrue() { + + func testEnableViewRendererV2True() { let optionsDict = ([ "dsn": "https://abc@def.ingest.sentry.io/1234567", "replaysOnErrorSampleRate": 0.75, - "mobileReplayOptions": [ "enableExperimentalViewRenderer": true ] + "mobileReplayOptions": [ "enableViewRendererV2": true ] ] as NSDictionary).mutableCopy() as! NSMutableDictionary RNSentryReplay.updateOptions(optionsDict) let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - XCTAssertTrue(actualOptions.sessionReplay.enableExperimentalViewRenderer) + XCTAssertTrue(actualOptions.sessionReplay.enableViewRendererV2) } - - func testEnableExperimentalViewRendererFalse() { + + func testEnableViewRendererV2False() { let optionsDict = ([ "dsn": "https://abc@def.ingest.sentry.io/1234567", "replaysOnErrorSampleRate": 0.75, - "mobileReplayOptions": [ "enableExperimentalViewRenderer": false ] + "mobileReplayOptions": [ "enableViewRendererV2": false ] ] as NSDictionary).mutableCopy() as! NSMutableDictionary RNSentryReplay.updateOptions(optionsDict) let actualOptions = try! Options(dict: optionsDict as! [String: Any]) - XCTAssertFalse(actualOptions.sessionReplay.enableExperimentalViewRenderer) + XCTAssertFalse(actualOptions.sessionReplay.enableViewRendererV2) } func testEnableFastViewRenderingDefault() { diff --git a/packages/core/ios/RNSentryReplay.mm b/packages/core/ios/RNSentryReplay.mm index 2b6745c82a..b616c975a8 100644 --- a/packages/core/ios/RNSentryReplay.mm +++ b/packages/core/ios/RNSentryReplay.mm @@ -27,8 +27,7 @@ + (void)updateOptions:(NSMutableDictionary *)options @"errorSampleRate" : options[@"replaysOnErrorSampleRate"] ?: [NSNull null], @"maskAllImages" : replayOptions[@"maskAllImages"] ?: [NSNull null], @"maskAllText" : replayOptions[@"maskAllText"] ?: [NSNull null], - @"enableExperimentalViewRenderer" : replayOptions[@"enableExperimentalViewRenderer"] - ?: [NSNull null], + @"enableViewRendererV2" : replayOptions[@"enableViewRendererV2"] ?: @YES, @"enableFastViewRendering" : replayOptions[@"enableFastViewRendering"] ?: [NSNull null], @"maskedViewClasses" : [RNSentryReplay getReplayRNRedactClasses:replayOptions], @"sdkInfo" : diff --git a/packages/core/src/js/replay/mobilereplay.ts b/packages/core/src/js/replay/mobilereplay.ts index 4bdfdd7955..1f260e9883 100644 --- a/packages/core/src/js/replay/mobilereplay.ts +++ b/packages/core/src/js/replay/mobilereplay.ts @@ -40,10 +40,24 @@ export interface MobileReplayOptions { * * - Experiment: This is an experimental feature and is therefore disabled by default. * - * @default false + * @deprecated Use `enableViewRendererV2` instead. */ enableExperimentalViewRenderer?: boolean; + /** + * Enables the up to 5x faster new view renderer used by the Session Replay integration on iOS. + * + * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing + * interruptions and visual lag. [Our benchmarks](https://github.com/getsentry/sentry-cocoa/pull/4940) have shown a significant improvement of + * **up to 4-5x faster rendering** (reducing `~160ms` to `~36ms` per frame) on older devices. + * + * - Experiment: In case you are noticing issues with the new view renderer, please report the issue on [GitHub](https://github.com/getsentry/sentry-cocoa). + * Eventually, we will remove this feature flag and use the new view renderer by default. + * + * @default true + */ + enableViewRendererV2?: boolean; + /** * Enables up to 5x faster but incomplete view rendering used by the Session Replay integration on iOS. * @@ -63,9 +77,23 @@ const defaultOptions: Required = { maskAllImages: true, maskAllVectors: true, enableExperimentalViewRenderer: false, + enableViewRendererV2: true, enableFastViewRendering: false, }; +function mergeOptions(initOptions: Partial): Required { + const merged = { + ...defaultOptions, + ...initOptions, + }; + + if (initOptions.enableViewRendererV2 === undefined && initOptions.enableExperimentalViewRenderer !== undefined) { + merged.enableViewRendererV2 = initOptions.enableExperimentalViewRenderer; + } + + return merged; +} + type MobileReplayIntegration = Integration & { options: Required; }; @@ -100,7 +128,7 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau return mobileReplayIntegrationNoop(); } - const options = { ...defaultOptions, ...initOptions }; + const options = mergeOptions(initOptions); async function processEvent(event: Event): Promise { const hasException = event.exception && event.exception.values && event.exception.values.length > 0; diff --git a/samples/react-native/src/App.tsx b/samples/react-native/src/App.tsx index 46a489952a..6b393f4e8f 100644 --- a/samples/react-native/src/App.tsx +++ b/samples/react-native/src/App.tsx @@ -100,7 +100,7 @@ Sentry.init({ maskAllImages: true, maskAllVectors: true, maskAllText: true, - enableExperimentalViewRenderer: true, + enableViewRendererV2: true, enableFastViewRendering: true, }), Sentry.appStartIntegration({ From bebd983090db54a9137c17e14f982e4e53950110 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 7 May 2025 11:19:59 +0300 Subject: [PATCH 2/4] Adds changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66df5e0e74..328484c274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ## Unreleased +### Changes + +- Renames `enableExperimentalViewRenderer` to `enableViewRendererV2` which is enabled by default for up to 5x times more performance in Session Replay on iOS ([#4815](https://github.com/getsentry/sentry-react-native/pull/4815)) + ### Dependencies - Bump CLI from v2.43.1 to v2.44.0 ([#4804](https://github.com/getsentry/sentry-react-native/pull/4804)) From 039815447f5b5908c85f4370485d7e39e8b5bb3a Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 8 May 2025 11:16:09 +0300 Subject: [PATCH 3/4] Fix doc comment wording Co-authored-by: LucasZF --- packages/core/src/js/replay/mobilereplay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/js/replay/mobilereplay.ts b/packages/core/src/js/replay/mobilereplay.ts index 1f260e9883..79aa1117ec 100644 --- a/packages/core/src/js/replay/mobilereplay.ts +++ b/packages/core/src/js/replay/mobilereplay.ts @@ -45,7 +45,7 @@ export interface MobileReplayOptions { enableExperimentalViewRenderer?: boolean; /** - * Enables the up to 5x faster new view renderer used by the Session Replay integration on iOS. + * Enables up to 5x faster new view renderer used by the Session Replay integration on iOS. * * Enabling this flag will reduce the amount of time it takes to render each frame of the session replay on the main thread, therefore reducing * interruptions and visual lag. [Our benchmarks](https://github.com/getsentry/sentry-cocoa/pull/4940) have shown a significant improvement of From 88280eb76756d1cb99474f615f1b5fcb80a0abc3 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Thu, 8 May 2025 15:12:54 +0300 Subject: [PATCH 4/4] Leave the undefined value as null so that it is set by the Cocoa SDK --- packages/core/ios/RNSentryReplay.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/ios/RNSentryReplay.mm b/packages/core/ios/RNSentryReplay.mm index b616c975a8..994ec36189 100644 --- a/packages/core/ios/RNSentryReplay.mm +++ b/packages/core/ios/RNSentryReplay.mm @@ -27,7 +27,7 @@ + (void)updateOptions:(NSMutableDictionary *)options @"errorSampleRate" : options[@"replaysOnErrorSampleRate"] ?: [NSNull null], @"maskAllImages" : replayOptions[@"maskAllImages"] ?: [NSNull null], @"maskAllText" : replayOptions[@"maskAllText"] ?: [NSNull null], - @"enableViewRendererV2" : replayOptions[@"enableViewRendererV2"] ?: @YES, + @"enableViewRendererV2" : replayOptions[@"enableViewRendererV2"] ?: [NSNull null], @"enableFastViewRendering" : replayOptions[@"enableFastViewRendering"] ?: [NSNull null], @"maskedViewClasses" : [RNSentryReplay getReplayRNRedactClasses:replayOptions], @"sdkInfo" :