Skip to content

Commit 2befc88

Browse files
fkgozalifacebook-github-bot
authored andcommitted
Expose the bridgeless performance logger and post RCTJavaScriptDidLoadNotification
Summary: In bridgeless mode, `RCTInstance` records native startup timings in a per-instance `RCTPerformanceLogger`, but that logger was never reachable from app code: `RCTBridgeProxy.performanceLogger` returned nil and `RCTJavaScriptDidLoadNotification` was never posted. Startup-perf consumers that follow the long-standing pattern of reading `[bridge performanceLogger]` on `RCTJavaScriptDidLoadNotification` were therefore silently inert under bridgeless, dropping all native startup timings. This restores that pattern for bridgeless: - `RCTBridgeProxy` now holds a real `performanceLogger` property, injected by `RCTInstance`, instead of returning nil. - `RCTInstance` posts `RCTJavaScriptDidLoadNotification` (on the main thread, with the bridge proxy in `userInfo[@"bridge"]`) once the JS bundle has loaded, mirroring the legacy bridge. No change to the legacy bridge path. Changelog: [iOS][Fixed] - Expose the bridgeless performance logger via `RCTBridgeProxy` and post `RCTJavaScriptDidLoadNotification`, so native startup-perf consumers work in bridgeless Differential Revision: D107542363
1 parent 02c5ab7 commit 2befc88

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

packages/react-native/React/Base/RCTBridgeProxy.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,21 @@ NS_ASSUME_NONNULL_BEGIN
1414
@class RCTBundleManager;
1515
@class RCTCallableJSModules;
1616
@class RCTModuleRegistry;
17+
@class RCTPerformanceLogger;
1718
@class RCTViewRegistry;
1819

1920
@interface RCTBridgeProxy : NSProxy
2021

2122
- (instancetype)init NS_UNAVAILABLE;
2223
+ (instancetype)new NS_UNAVAILABLE;
2324

25+
/**
26+
* The performance logger for this React instance. In bridgeless mode it is
27+
* injected by RCTInstance so that consumers reading `[bridge performanceLogger]`
28+
* on `RCTJavaScriptDidLoadNotification` keep working; previously it returned nil.
29+
*/
30+
@property (nonatomic, strong, nullable) RCTPerformanceLogger *performanceLogger;
31+
2432
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
2533
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
2634
bundleManager:(RCTBundleManager *)bundleManager

packages/react-native/React/Base/RCTBridgeProxy.mm

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ @implementation RCTBridgeProxy {
4141
void *_runtime;
4242
}
4343

44+
@synthesize performanceLogger = _performanceLogger;
45+
4446
#pragma clang diagnostic push
4547
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
4648
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
@@ -213,12 +215,6 @@ - (BOOL)valid
213215
return NO;
214216
}
215217

216-
- (RCTPerformanceLogger *)performanceLogger
217-
{
218-
[self logWarning:@"This method is not supported. Returning nil." cmd:_cmd];
219-
return nil;
220-
}
221-
222218
- (void)reload
223219
{
224220
[self logError:@"Please use RCTReloadCommand instead. Nooping." cmd:_cmd];

packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ @implementation RCTInstance {
115115
RCTPerformanceLogger *_performanceLogger;
116116
RCTDisplayLink *_displayLink;
117117
RCTTurboModuleManager *_turboModuleManager;
118+
RCTBridgeProxy *_bridgeProxy;
118119
std::mutex _invalidationMutex;
119120
std::atomic<bool> _valid;
120121
RCTJSThreadManager *_jsThreadManager;
@@ -351,6 +352,8 @@ - (void)_start
351352
runtime:_reactInstance->getJavaScriptContext()
352353
launchOptions:_launchOptions];
353354
bridgeProxy.jsCallInvoker = jsCallInvoker;
355+
bridgeProxy.performanceLogger = _performanceLogger;
356+
_bridgeProxy = bridgeProxy;
354357
[RCTBridge setCurrentBridge:(RCTBridge *)bridgeProxy];
355358

356359
// Set up TurboModules
@@ -606,8 +609,20 @@ - (void)_loadScriptFromSource:(RCTSource *)source
606609
waitUntilModuleSetupComplete();
607610
}
608611
};
609-
auto afterLoad = [](jsi::Runtime &_) {
612+
__weak __typeof(self) weakSelf = self;
613+
auto afterLoad = [weakSelf](jsi::Runtime &) {
610614
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTInstanceDidLoadBundle" object:nil];
615+
__strong __typeof(weakSelf) strongSelf = weakSelf;
616+
if (strongSelf) {
617+
RCTBridgeProxy *bridgeProxy = strongSelf->_bridgeProxy;
618+
// afterLoad runs on the JS thread; post on main like the legacy bridge so
619+
// RCTJavaScriptDidLoadNotification observers aren't invoked off-main.
620+
RCTExecuteOnMainQueue(^{
621+
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
622+
object:strongSelf
623+
userInfo:bridgeProxy ? @{@"bridge" : bridgeProxy} : @{}];
624+
});
625+
}
611626
};
612627
_reactInstance->loadScript(std::move(script), url, beforeLoad, afterLoad);
613628
}

0 commit comments

Comments
 (0)