Skip to content

Commit

Permalink
Introduce Module Setup Metric (#23859)
Browse files Browse the repository at this point in the history
Summary:
The `RCTBridge` contains numerous definitions of notification names, which we can observe in order to get insights into the React Native performance.

The Android implementation is a little different, such that you can listen for any of the [following](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java) marker constants, simply by including the following code:

```java
ReactMarker.addListener(new ReactMarker.MarkerListener() {
  Override
  public void logMarker(ReactMarkerConstants name, Nullable String tag, int instanceKey) {
    Log.d("ReactNativeEvent", "name: "+ name.name() + " tag: " + tag);
  }
});
```
This will allow you to perform the necessary processing, calculations as required.

 ---

This PR enables observing for the module setup event (`RCTDidSetupModuleNotification`) by including the respective module's name & setup time in milliseconds.

[iOS] [Added] - Gain insights on the 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: #23859

Differential Revision: D14579066

Pulled By: PeteTheHeat

fbshipit-source-id: 52645127c3fc6aa5bd73e3bd471fccd79cb05c14
  • Loading branch information
a-dilettante authored and facebook-github-bot committed Mar 22, 2019
1 parent f9a344c commit e2bf843
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 2 deletions.
19 changes: 19 additions & 0 deletions React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ 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
* `RCTDidSetupModuleNotificationModuleNameKey` key will contain a reference to the module name and
* `RCTDidSetupModuleNotificationSetupTimeKey` will contain the setup time in ms.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotification;

/**
* Key for the module name (NSString) in the
* RCTDidSetupModuleNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationModuleNameKey;

/**
* Key for the setup time (NSNumber) in the
* RCTDidSetupModuleNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationSetupTimeKey;

/**
* This notification fires just before the bridge starts processing a request to
* reload.
Expand Down
3 changes: 3 additions & 0 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
NSString *const RCTJavaScriptDidLoadNotification = @"RCTJavaScriptDidLoadNotification";
NSString *const RCTJavaScriptDidFailToLoadNotification = @"RCTJavaScriptDidFailToLoadNotification";
NSString *const RCTDidInitializeModuleNotification = @"RCTDidInitializeModuleNotification";
NSString *const RCTDidSetupModuleNotification = @"RCTDidSetupModuleNotification";
NSString *const RCTDidSetupModuleNotificationModuleNameKey = @"moduleName";
NSString *const RCTDidSetupModuleNotificationSetupTimeKey = @"setupTime";
NSString *const RCTBridgeWillReloadNotification = @"RCTBridgeWillReloadNotification";
NSString *const RCTBridgeWillDownloadScriptNotification = @"RCTBridgeWillDownloadScriptNotification";
NSString *const RCTBridgeDidDownloadScriptNotification = @"RCTBridgeDidDownloadScriptNotification";
Expand Down
1 change: 1 addition & 0 deletions React/Base/RCTPerformanceLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) {
RCTPLNativeModuleMainThread,
RCTPLNativeModulePrepareConfig,
RCTPLNativeModuleMainThreadUsesCount,
RCTPLNativeModuleSetup,
RCTPLJSCWrapperOpenLibrary,
RCTPLBridgeStartup,
RCTPLTTI,
Expand Down
1 change: 1 addition & 0 deletions React/Base/RCTPerformanceLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ - (instancetype)init
@"NativeModulePrepareConfig",
@"NativeModuleInjectConfig",
@"NativeModuleMainThreadUsesCount",
@"NativeModuleSetup",
@"JSCWrapperOpenLibrary",
@"JSCExecutorSetup",
@"BridgeStartup",
Expand Down
22 changes: 20 additions & 2 deletions React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ static bool isRAMBundle(NSData *script) {
return parseTypeFromHeader(header) == ScriptTag::RAMBundle;
}

static void notifyAboutModuleSetup(RCTPerformanceLogger *performanceLogger, const char *tag) {
NSString *moduleName = [[NSString alloc] initWithUTF8String:tag];
if (moduleName) {
int64_t setupTime = [performanceLogger durationForTag:RCTPLNativeModuleSetup];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTDidSetupModuleNotification
object:nil
userInfo:@{
RCTDidSetupModuleNotificationModuleNameKey: moduleName,
RCTDidSetupModuleNotificationSetupTimeKey: @(setupTime)
}];
}
}

static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogger) {
__weak RCTPerformanceLogger *weakPerformanceLogger = performanceLogger;
ReactMarker::logTaggedMarker = [weakPerformanceLogger](const ReactMarker::ReactMarkerId markerId, const char *__unused tag) {
Expand All @@ -116,11 +129,16 @@ static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogg
[weakPerformanceLogger appendStopForTag:RCTPLRAMNativeRequires];
[weakPerformanceLogger addValue:1 forTag:RCTPLRAMNativeRequiresCount];
break;
case ReactMarker::NATIVE_MODULE_SETUP_START:
[weakPerformanceLogger markStartForTag:RCTPLNativeModuleSetup];
break;
case ReactMarker::NATIVE_MODULE_SETUP_STOP:
[weakPerformanceLogger markStopForTag:RCTPLNativeModuleSetup];
notifyAboutModuleSetup(weakPerformanceLogger, tag);
break;
case ReactMarker::CREATE_REACT_CONTEXT_STOP:
case ReactMarker::JS_BUNDLE_STRING_CONVERT_START:
case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP:
case ReactMarker::NATIVE_MODULE_SETUP_START:
case ReactMarker::NATIVE_MODULE_SETUP_STOP:
case ReactMarker::REGISTER_JS_SEGMENT_START:
case ReactMarker::REGISTER_JS_SEGMENT_STOP:
// These are not used on iOS.
Expand Down

0 comments on commit e2bf843

Please sign in to comment.