Skip to content

Commit 57085ce

Browse files
authored
Fix bridgeless mode on iOS (#115)
1 parent 74e0120 commit 57085ce

File tree

3 files changed

+42
-20
lines changed

3 files changed

+42
-20
lines changed

examples/vanilla/ios/Example/AppDelegate.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import React
33
import React_RCTAppDelegate
44
import ReactAppDependencyProvider
55

6-
76
@main
87
class AppDelegate: RCTAppDelegate {
98
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
@@ -13,7 +12,7 @@ class AppDelegate: RCTAppDelegate {
1312
// You can add your custom initial props in the dictionary below.
1413
// They will be passed down to the ViewController used by React Native.
1514
self.initialProps = [:]
16-
RNPerformance.sharedInstance().mark("myCustomMark")
15+
RNPerformance.sharedInstance().mark("myCustomMark", ephemeral: false)
1716
/*
1817
[RNPerformance.sharedInstance mark:@"myCustomMark"];
1918
[RNPerformance.sharedInstance mark:@"myCustomMark" detail:@{ @"extra": @"info" }];

packages/react-native-performance/ios/RNPerformanceEntry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#import <Foundation/Foundation.h>
2+
13
typedef enum EntryType : NSUInteger {
24
kMark,
35
kMetric

packages/react-native-performance/ios/RNPerformanceManager.mm

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#import <QuartzCore/QuartzCore.h>
55
#import <React/RCTRootView.h>
66
#import <React/RCTPerformanceLogger.h>
7+
#import <cxxreact/ReactMarker.h>
8+
79
#import "RNPerformanceUtils.h"
810

911
#ifdef RCT_NEW_ARCH_ENABLED
@@ -13,10 +15,13 @@
1315
static int64_t sNativeLaunchStart;
1416
static int64_t sNativeLaunchEnd;
1517

18+
using namespace facebook::react;
19+
1620
@implementation RNPerformanceManager
1721
{
1822
bool hasListeners;
1923
bool didEmit;
24+
int64_t contentAppeared;
2025
}
2126

2227
RCT_EXPORT_MODULE();
@@ -30,12 +35,22 @@ + (void) initialize
3035
sNativeLaunchStart = sNativeLaunchEnd - (tp.tv_sec * 1e3 + tp.tv_nsec / 1e6);
3136
}
3237

38+
- (instancetype)init
39+
{
40+
if (self = [super init]) {
41+
hasListeners = NO;
42+
didEmit = NO;
43+
contentAppeared = -1;
44+
}
45+
return self;
46+
}
47+
3348
- (void)setBridge:(RCTBridge *)bridge
3449
{
3550
[super setBridge:bridge];
3651
[RNPerformance.sharedInstance clearEphemeralEntries];
3752
[[NSNotificationCenter defaultCenter] addObserver:self
38-
selector:@selector(emitIfReady)
53+
selector:@selector(contentAppeared)
3954
name:RCTContentDidAppearNotification
4055
object:nil];
4156
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -48,9 +63,20 @@ - (void)setBridge:(RCTBridge *)bridge
4863
object:nil];
4964
}
5065

66+
- (BOOL)isReady
67+
{
68+
return contentAppeared != -1 && !std::isnan(ReactMarker::StartupLogger::getInstance().getRunJSBundleEndTime());
69+
}
70+
71+
- (void) contentAppeared
72+
{
73+
contentAppeared = RNPerformanceGetTimestamp();
74+
[self emitIfReady];
75+
}
76+
5177
- (void)emitIfReady
5278
{
53-
if (!didEmit && hasListeners && [self.bridge.performanceLogger valueForTag:RCTPLTTI] != 0 && [self.bridge.performanceLogger valueForTag:RCTPLScriptExecution] != 0) {
79+
if (!didEmit && hasListeners && [self isReady]) {
5480
[self emitEntries];
5581
}
5682
}
@@ -67,10 +93,13 @@ - (void)emitEntries
6793
didEmit = YES;
6894
[self emitMarkNamed:@"nativeLaunchStart" withStartTime:sNativeLaunchStart];
6995
[self emitMarkNamed:@"nativeLaunchEnd" withStartTime:sNativeLaunchEnd];
70-
[self emitTag:RCTPLScriptDownload withNamePrefix:@"download"];
71-
[self emitTag:RCTPLScriptExecution withNamePrefix:@"runJsBundle"];
72-
[self emitTag:RCTPLBridgeStartup withNamePrefix:@"bridgeSetup"];
73-
[self emitMarkNamed:@"contentAppeared" withMediaTime:[self.bridge.performanceLogger valueForTag:RCTPLTTI]];
96+
[self emitMarkNamed:@"runJsBundleStart" withMediaTime:ReactMarker::StartupLogger::getInstance().getRunJSBundleStartTime()];
97+
[self emitMarkNamed:@"runJsBundleEnd" withMediaTime:ReactMarker::StartupLogger::getInstance().getRunJSBundleEndTime()];
98+
[self emitMarkNamed:@"appStartupStart" withMediaTime:ReactMarker::StartupLogger::getInstance().getAppStartupStartTime()];
99+
[self emitMarkNamed:@"appStartupEnd" withMediaTime:ReactMarker::StartupLogger::getInstance().getAppStartupEndTime()];
100+
[self emitMarkNamed:@"initReactRuntimeStart" withMediaTime:ReactMarker::StartupLogger::getInstance().getInitReactRuntimeStartTime()];
101+
[self emitMarkNamed:@"initReactRuntimeEnd" withMediaTime:ReactMarker::StartupLogger::getInstance().getInitReactRuntimeEndTime()];
102+
[self emitMarkNamed:@"contentAppeared" withStartTime:contentAppeared];
74103
[self emitMetricNamed:@"bundleSize" withValue:@([self.bridge.performanceLogger valueForTag:RCTPLBundleSize]) withStartTime:RNPerformanceGetTimestamp() withDetail:@{ @"unit": @"byte" }];
75104
[[RNPerformance.sharedInstance getEntries]
76105
enumerateObjectsUsingBlock:^(RNPerformanceEntry * _Nonnull entry, NSUInteger idx, BOOL * _Nonnull stop) {
@@ -106,7 +135,7 @@ - (void)invalidate
106135
- (void)startObserving
107136
{
108137
hasListeners = YES;
109-
if (didEmit != YES && [self.bridge.performanceLogger valueForTag:RCTPLTTI] != 0 && [self.bridge.performanceLogger valueForTag:RCTPLScriptExecution] != 0) {
138+
if (didEmit != YES && [self isReady]) {
110139
[self emitEntries];
111140
}
112141
}
@@ -116,20 +145,12 @@ -(void)stopObserving
116145
hasListeners = NO;
117146
}
118147

119-
- (void)emitTag:(RCTPLTag)tag withNamePrefix:(NSString *)namePrefix
148+
- (void)emitMarkNamed:(NSString *)name withMediaTime:(int64_t)mediaTime
120149
{
121-
int64_t duration = [self.bridge.performanceLogger durationForTag:tag];
122-
int64_t end = [self.bridge.performanceLogger valueForTag:tag];
123-
if (duration == 0 || end == 0) {
124-
NSLog(@"Ignoring marks prefixed %@ (%lu) as data is unavailable (duration: %lld, end: %lld)", namePrefix, (unsigned long)tag, duration, end);
150+
if (mediaTime == 0) {
151+
NSLog(@"Ignoring mark named %@ as timestamp is not set", name);
125152
return;
126153
}
127-
[self emitMarkNamed:[namePrefix stringByAppendingString:@"Start"] withMediaTime:end-duration];
128-
[self emitMarkNamed:[namePrefix stringByAppendingString:@"End"] withMediaTime:end];
129-
}
130-
131-
- (void)emitMarkNamed:(NSString *)name withMediaTime:(int64_t)mediaTime
132-
{
133154
[self emitMarkNamed:name withStartTime:mediaTime + RNPerformanceGetTimestamp() - (CACurrentMediaTime() * 1000)];
134155
}
135156

0 commit comments

Comments
 (0)