From 64b5d5222da67b4ab6efd1ced77190b18b8346da Mon Sep 17 00:00:00 2001 From: RCiesielczuk Date: Wed, 15 May 2019 15:24:53 -0700 Subject: [PATCH] Introduce TurboModule Setup Metric (#24732) Summary: With the introduction of TurboModules, it would be beneficial to measure the setup time of these modules, as we currently have it in place for NativeModules. The instantiation of the TMs occurs in the `RCTTurboModuleManager`. In order to successfully measure the time it took to setup the module, we need to ensure that we don't take into account cached modules. As such, we need to: 1. Check if module is in `_turboModuleCache` a. Start mark for `RCTPLTurboModuleSetup` tag if not found 2. Get the TM via `[self provideTurboModule:]` 3. Check if module is in `_turboModuleCache` a. Stop mark for `RCTPLTurboModuleSetup` if we did not find module in cache prior to **step 2** and if it's now present in the cache. b. Notify about setup time if the above is true. 4. Return TM ## Changelog [iOS] [Added] - Gain insights on the the turbo module setup times by observing `RCTDidSetupModuleNotification`. The userInfo dictionary will contain the module name and setup time in milliseconds. These values can be extracted via `RCTDidSetupModuleNotificationModuleNameKey` and `RCTDidSetupModuleNotificationSetupTimeKey`. Pull Request resolved: https://github.com/facebook/react-native/pull/24732 Differential Revision: D15362088 Pulled By: RSNara fbshipit-source-id: e6a8044e4aba5a12ae63e9c7dbf707a17ec00180 --- React/Base/RCTBridge.h | 2 +- React/Base/RCTPerformanceLogger.h | 1 + React/Base/RCTPerformanceLogger.m | 1 + .../platform/ios/RCTTurboModuleManager.mm | 29 ++++++++++++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) 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 85e16f25c5f1c8..5fc66fa67262d2 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 @@ -65,12 +66,25 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id_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); @@ -78,6 +92,19 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id_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.