Skip to content

Commit cd2f8c5

Browse files
a-dilettantefacebook-github-bot
authored andcommitted
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: #24732 Differential Revision: D15362088 Pulled By: RSNara fbshipit-source-id: e6a8044e4aba5a12ae63e9c7dbf707a17ec00180
1 parent 36f9a4a commit cd2f8c5

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

React/Base/RCTBridge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification;
4949
RCT_EXTERN NSString *const RCTDidInitializeModuleNotification;
5050

5151
/**
52-
* This notification fires each time a native module is setup after it is initialized. The
52+
* This notification fires each time a module is setup after it is initialized. The
5353
* `RCTDidSetupModuleNotificationModuleNameKey` key will contain a reference to the module name and
5454
* `RCTDidSetupModuleNotificationSetupTimeKey` will contain the setup time in ms.
5555
*/

React/Base/RCTPerformanceLogger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) {
2121
RCTPLNativeModulePrepareConfig,
2222
RCTPLNativeModuleMainThreadUsesCount,
2323
RCTPLNativeModuleSetup,
24+
RCTPLTurboModuleSetup,
2425
RCTPLJSCWrapperOpenLibrary,
2526
RCTPLBridgeStartup,
2627
RCTPLTTI,

React/Base/RCTPerformanceLogger.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ - (instancetype)init
4242
@"NativeModuleInjectConfig",
4343
@"NativeModuleMainThreadUsesCount",
4444
@"NativeModuleSetup",
45+
@"TurboModuleSetup",
4546
@"JSCWrapperOpenLibrary",
4647
@"JSCExecutorSetup",
4748
@"BridgeStartup",

ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#import <cassert>
1111

1212
#import <React/RCTBridge+Private.h>
13+
#import <React/RCTPerformanceLogger.h>
1314
#import <React/RCTBridgeModule.h>
1415
#import <React/RCTCxxModule.h>
1516
#import <React/RCTLog.h>
@@ -65,19 +66,45 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id<RCTTurboModuleMa
6566

6667
__strong __typeof(self) strongSelf = weakSelf;
6768

69+
auto moduleName = name.c_str();
70+
auto moduleWasNotInitialized = ![strongSelf moduleIsInitialized:moduleName];
71+
if (moduleWasNotInitialized) {
72+
[strongSelf->_bridge.performanceLogger markStartForTag:RCTPLTurboModuleSetup];
73+
}
74+
6875
/**
6976
* By default, all TurboModules are long-lived.
7077
* Additionally, if a TurboModule with the name `name` isn't found, then we
7178
* trigger an assertion failure.
7279
*/
73-
return [strongSelf provideTurboModule: name.c_str()];
80+
auto turboModule = [strongSelf provideTurboModule:moduleName];
81+
82+
if (moduleWasNotInitialized && [strongSelf moduleIsInitialized:moduleName]) {
83+
[strongSelf->_bridge.performanceLogger markStopForTag:RCTPLTurboModuleSetup];
84+
[strongSelf notifyAboutTurboModuleSetup:moduleName];
85+
}
86+
87+
return turboModule;
7488
};
7589

7690
_binding = std::make_shared<react::TurboModuleBinding>(moduleProvider);
7791
}
7892
return self;
7993
}
8094

95+
- (void)notifyAboutTurboModuleSetup:(const char*)name {
96+
NSString *moduleName = [[NSString alloc] initWithUTF8String:name];
97+
if (moduleName) {
98+
int64_t setupTime = [self->_bridge.performanceLogger durationForTag:RCTPLTurboModuleSetup];
99+
[[NSNotificationCenter defaultCenter] postNotificationName:RCTDidSetupModuleNotification
100+
object:nil
101+
userInfo:@{
102+
RCTDidSetupModuleNotificationModuleNameKey: moduleName,
103+
RCTDidSetupModuleNotificationSetupTimeKey: @(setupTime)
104+
}];
105+
}
106+
}
107+
81108
/**
82109
* Given a name for a TurboModule, return a C++ object which is the instance
83110
* of that TurboModule C++ class. This class wraps the TurboModule's ObjC instance.

0 commit comments

Comments
 (0)