From 259161f8729e43672dd90c03374fb3cebaf11967 Mon Sep 17 00:00:00 2001 From: Ben Nham Date: Thu, 31 Aug 2017 05:25:19 -0700 Subject: [PATCH] add files changed count to reload metrics Reviewed By: alexeylang Differential Revision: D5694813 fbshipit-source-id: 2e2517e60a7547e261a7c15a3a9138dbb3cb9783 --- React/Base/RCTBridge.h | 6 ++++++ React/Base/RCTBridge.m | 1 + React/Base/RCTJavaScriptLoader.h | 14 ++++++++++++++ React/Base/RCTJavaScriptLoader.mm | 10 +++++++++- React/CxxBridge/RCTCxxBridge.mm | 4 +++- 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 889c4b3e5..214714f64 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -62,6 +62,12 @@ RCT_EXTERN NSString *const RCTBridgeWillDownloadScriptNotification; */ RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotification; +/** + * Key for the RCTSource object in the RCTBridgeDidDownloadScriptNotification + * userInfo dictionary. + */ +RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey; + /** * This block can be used to instantiate modules that require additional * init parameters, or additional configuration prior to being used. diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index b4feb1d33..e9b6b87fa 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -32,6 +32,7 @@ NSString *const RCTDidInitializeModuleNotification = @"RCTDidInitializeModuleNot NSString *const RCTBridgeWillReloadNotification = @"RCTBridgeWillReloadNotification"; NSString *const RCTBridgeWillDownloadScriptNotification = @"RCTBridgeWillDownloadScriptNotification"; NSString *const RCTBridgeDidDownloadScriptNotification = @"RCTBridgeDidDownloadScriptNotification"; +NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey = @"source"; static NSMutableArray *RCTModuleClasses; NSArray *RCTGetModuleClasses(void) diff --git a/React/Base/RCTJavaScriptLoader.h b/React/Base/RCTJavaScriptLoader.h index 08cf7e420..641b1ce6f 100755 --- a/React/Base/RCTJavaScriptLoader.h +++ b/React/Base/RCTJavaScriptLoader.h @@ -25,6 +25,11 @@ NS_ENUM(NSInteger) { RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000, }; +NS_ENUM(NSInteger) { + RCTSourceFilesChangedCountNotBuiltByBundler = -2, + RCTSourceFilesChangedCountRebuiltFromScratch = -1, +}; + @interface RCTLoadingProgress : NSObject @property (nonatomic, copy) NSString *status; @@ -55,6 +60,15 @@ NS_ENUM(NSInteger) { */ @property (nonatomic, readonly) NSUInteger length; +/** + * Returns number of files changed when building this bundle: + * + * - RCTSourceFilesChangedCountNotBuiltByBundler if the source wasn't built by the bundler (e.g. read from disk) + * - RCTSourceFilesChangedCountRebuiltFromScratch if the source was rebuilt from scratch by the bundler + * - Otherwise, the number of files changed when incrementally rebuilding the source + */ +@property (nonatomic, readonly) NSInteger filesChangedCount; + @end typedef void (^RCTSourceLoadProgressBlock)(RCTLoadingProgress *progressData); diff --git a/React/Base/RCTJavaScriptLoader.mm b/React/Base/RCTJavaScriptLoader.mm index 2e531b58b..80871c6a3 100755 --- a/React/Base/RCTJavaScriptLoader.mm +++ b/React/Base/RCTJavaScriptLoader.mm @@ -28,6 +28,7 @@ NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomai NSURL *_url; NSData *_data; NSUInteger _length; + NSInteger _filesChangedCount; } @end @@ -40,6 +41,7 @@ static RCTSource *RCTSourceCreate(NSURL *url, NSData *data, int64_t length) NS_R source->_url = url; source->_data = data; source->_length = length; + source->_filesChangedCount = RCTSourceFilesChangedCountNotBuiltByBundler; return source; } @@ -205,6 +207,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) return [NSData dataWithBytes:&header length:sizeof(header)]; } +static void parseHeaders(NSDictionary *headers, RCTSource *source) { + source->_filesChangedCount = [headers[@"X-Metro-Files-Changed-Count"] integerValue]; +} + static void attemptAsynchronousLoadOfBundleAtURL(NSURL *scriptURL, RCTSourceLoadProgressBlock onProgress, RCTSourceLoadBlock onComplete) { scriptURL = sanitizeURL(scriptURL); @@ -282,7 +288,9 @@ static void attemptAsynchronousLoadOfBundleAtURL(NSURL *scriptURL, RCTSourceLoad return; } - onComplete(nil, RCTSourceCreate(scriptURL, data, data.length)); + RCTSource *source = RCTSourceCreate(scriptURL, data, data.length); + parseHeaders(headers, source); + onComplete(nil, source); } progressHandler:^(NSDictionary *headers, NSNumber *loaded, NSNumber *total) { // Only care about download progress events for the javascript bundle part. if ([headers[@"Content-Type"] isEqualToString:@"application/javascript"]) { diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 5883b7173..be29341e3 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -390,7 +390,9 @@ struct RCTInstanceCallback : public InstanceCallback { RCTProfileEndAsyncEvent(0, @"native", cookie, @"JavaScript download", @"JS async"); [performanceLogger markStopForTag:RCTPLScriptDownload]; [performanceLogger setValue:source.length forTag:RCTPLBundleSize]; - [center postNotificationName:RCTBridgeDidDownloadScriptNotification object:self->_parentBridge]; + + NSDictionary *userInfo = source ? @{ RCTBridgeDidDownloadScriptNotificationSourceKey: source } : nil; + [center postNotificationName:RCTBridgeDidDownloadScriptNotification object:self->_parentBridge userInfo:userInfo]; _onSourceLoad(error, source); };