From 145ee42267d07a6d58c457c1e0b879f8bb42eb43 Mon Sep 17 00:00:00 2001 From: Rafi Ciesielczuk Date: Mon, 11 Mar 2019 15:49:03 +0000 Subject: [PATCH 1/2] Introduce module setup time metric --- React/Base/RCTBridge.h | 19 +++++++++++++++++++ React/Base/RCTBridge.m | 3 +++ React/Base/RCTPerformanceLogger.h | 1 + React/Base/RCTPerformanceLogger.m | 1 + React/CxxBridge/RCTCxxBridge.mm | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+) diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index a9150471d547..b8a394572d84 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -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. diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 0ff789cf44c8..ec16993a5cb5 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -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"; diff --git a/React/Base/RCTPerformanceLogger.h b/React/Base/RCTPerformanceLogger.h index f1a615f49e41..5e540dc8d4db 100644 --- a/React/Base/RCTPerformanceLogger.h +++ b/React/Base/RCTPerformanceLogger.h @@ -20,6 +20,7 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) { RCTPLNativeModuleMainThread, RCTPLNativeModulePrepareConfig, RCTPLNativeModuleMainThreadUsesCount, + RCTPLNativeModuleSetup, RCTPLJSCWrapperOpenLibrary, RCTPLBridgeStartup, RCTPLTTI, diff --git a/React/Base/RCTPerformanceLogger.m b/React/Base/RCTPerformanceLogger.m index af7cc7118c8f..1d728f34a3f2 100644 --- a/React/Base/RCTPerformanceLogger.m +++ b/React/Base/RCTPerformanceLogger.m @@ -41,6 +41,7 @@ - (instancetype)init @"NativeModulePrepareConfig", @"NativeModuleInjectConfig", @"NativeModuleMainThreadUsesCount", + @"NativeModuleSetup", @"JSCWrapperOpenLibrary", @"JSCExecutorSetup", @"BridgeStartup", diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 3c56f756f54d..0100fbea8a83 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -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) { @@ -120,7 +133,12 @@ static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogg case ReactMarker::JS_BUNDLE_STRING_CONVERT_START: case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP: 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::REGISTER_JS_SEGMENT_START: case ReactMarker::REGISTER_JS_SEGMENT_STOP: // These are not used on iOS. From d38a571fded6ca08cd70f8c34365d8e2001789fb Mon Sep 17 00:00:00 2001 From: Rafi Ciesielczuk Date: Wed, 13 Mar 2019 19:07:05 +0000 Subject: [PATCH 2/2] Move order of module setup markers in switch statement --- React/CxxBridge/RCTCxxBridge.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 0100fbea8a83..ca8a1b117e96 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -129,9 +129,6 @@ static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogg [weakPerformanceLogger appendStopForTag:RCTPLRAMNativeRequires]; [weakPerformanceLogger addValue:1 forTag:RCTPLRAMNativeRequiresCount]; 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: [weakPerformanceLogger markStartForTag:RCTPLNativeModuleSetup]; break; @@ -139,6 +136,9 @@ static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogg [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::REGISTER_JS_SEGMENT_START: case ReactMarker::REGISTER_JS_SEGMENT_STOP: // These are not used on iOS.