diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index b8a394572d8451..130c87a0a6b447 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -49,7 +49,7 @@ RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification; RCT_EXTERN NSString *const RCTDidInitializeModuleNotification; /** - * This notification fires each time a native module is setup after it is initialized. The + * This notification fires each time a module is setup after it is initialized. The * `RCTDidSetupModuleNotificationModuleNameKey` key will contain a reference to the module name and * `RCTDidSetupModuleNotificationSetupTimeKey` will contain the setup time in ms. */ diff --git a/React/Base/RCTPerformanceLogger.h b/React/Base/RCTPerformanceLogger.h index 5e540dc8d4db2f..2562dc8f15899d 100644 --- a/React/Base/RCTPerformanceLogger.h +++ b/React/Base/RCTPerformanceLogger.h @@ -21,6 +21,7 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) { RCTPLNativeModulePrepareConfig, RCTPLNativeModuleMainThreadUsesCount, RCTPLNativeModuleSetup, + RCTPLTurboModuleSetup, RCTPLJSCWrapperOpenLibrary, RCTPLBridgeStartup, RCTPLTTI, diff --git a/React/Base/RCTPerformanceLogger.m b/React/Base/RCTPerformanceLogger.m index 1d728f34a3f265..f1186267a84671 100644 --- a/React/Base/RCTPerformanceLogger.m +++ b/React/Base/RCTPerformanceLogger.m @@ -42,6 +42,7 @@ - (instancetype)init @"NativeModuleInjectConfig", @"NativeModuleMainThreadUsesCount", @"NativeModuleSetup", + @"TurboModuleSetup", @"JSCWrapperOpenLibrary", @"JSCExecutorSetup", @"BridgeStartup", diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index 54afb7b31b6ccc..0db6982d860456 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -10,6 +10,7 @@ #import #import +#import #import #import #import @@ -67,12 +68,25 @@ - (instancetype)initWithRuntime:(jsi::Runtime *)runtime __strong __typeof(self) strongSelf = weakSelf; + auto moduleName = name.c_str(); + auto moduleWasNotInitialized = ![strongSelf moduleIsInitialized:moduleName]; + if (moduleWasNotInitialized) { + [strongSelf->_bridge.performanceLogger markStartForTag:RCTPLTurboModuleSetup]; + } + /** * By default, all TurboModules are long-lived. * Additionally, if a TurboModule with the name `name` isn't found, then we * trigger an assertion failure. */ - return [strongSelf provideTurboModule: name.c_str()]; + auto turboModule = [strongSelf provideTurboModule:moduleName]; + + if (moduleWasNotInitialized && [strongSelf moduleIsInitialized:moduleName]) { + [strongSelf->_bridge.performanceLogger markStopForTag:RCTPLTurboModuleSetup]; + [strongSelf notifyAboutTurboModuleSetup:moduleName]; + } + + return turboModule; }; _binding = std::make_shared(moduleProvider); @@ -80,6 +94,19 @@ - (instancetype)initWithRuntime:(jsi::Runtime *)runtime return self; } +- (void)notifyAboutTurboModuleSetup:(const char*)name { + NSString *moduleName = [[NSString alloc] initWithUTF8String:name]; + if (moduleName) { + int64_t setupTime = [self->_bridge.performanceLogger durationForTag:RCTPLTurboModuleSetup]; + [[NSNotificationCenter defaultCenter] postNotificationName:RCTDidSetupModuleNotification + object:nil + userInfo:@{ + RCTDidSetupModuleNotificationModuleNameKey: moduleName, + RCTDidSetupModuleNotificationSetupTimeKey: @(setupTime) + }]; + } +} + /** * Given a name for a TurboModule, return a C++ object which is the instance * of that TurboModule C++ class. This class wraps the TurboModule's ObjC instance.