Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e6c07e3
Create a new AppReadyActivity and expose it to RN
antonis Nov 19, 2024
26ff4dd
Start AppReadyActivity when JS loads
antonis Nov 19, 2024
0bc61ca
Measure startup time with the AppReadyActivity
antonis Nov 19, 2024
0a810f0
Reset diffMin workaround introduced with #4159
antonis Nov 19, 2024
1cc99e0
Start activity only on Android
antonis Nov 19, 2024
c8ede29
Don't close the activity to avoid any delay
antonis Nov 19, 2024
8bdc153
Remove unneeded comments
antonis Nov 19, 2024
b735f2b
Cleanup
antonis Nov 19, 2024
d1ccf92
Merge branch 'main' into antonis/3413-android-app-start-metric
antonis Nov 19, 2024
219696a
Point to updated StartupTimeTest
antonis Nov 20, 2024
8b09d83
Updates metrics library hash
antonis Nov 20, 2024
dd6d674
Update metrics lib
antonis Nov 20, 2024
f96d7d3
Update metric lib
antonis Nov 20, 2024
77e1437
Update metrics lib
antonis Nov 20, 2024
b13c465
update metrics lib
antonis Nov 20, 2024
cbfe08b
Update metric lib
antonis Nov 20, 2024
4f04935
Update metrics lib
antonis Nov 20, 2024
a3f2ea9
update metric lib
antonis Nov 20, 2024
23bbdf6
Update metrics lib
antonis Nov 20, 2024
f48e5a0
Update metric lib
antonis Nov 20, 2024
25eccc7
Update metrics lib
antonis Nov 20, 2024
a139043
Log app is ready at timestamp (ms)
antonis Nov 20, 2024
c95b819
Log app ready timestamp
antonis Nov 21, 2024
33744f2
Update log format
antonis Nov 21, 2024
ab8b897
update metrics lib
antonis Nov 21, 2024
6aac156
Update lib
antonis Nov 21, 2024
acf1798
Update lib
antonis Nov 21, 2024
ba01fc9
Use appLoadedLog
antonis Nov 21, 2024
b8f793e
Try useAppWaitActivity
antonis Nov 22, 2024
0be394e
Update lib
antonis Nov 22, 2024
54745a0
Update lib
antonis Nov 22, 2024
471b514
update lib
antonis Nov 22, 2024
1882a3e
Merge branch 'main' into antonis/3413-android-app-start-metric
antonis Dec 3, 2024
337e334
Update lib
antonis Dec 3, 2024
7ffb630
Update lib
antonis Dec 3, 2024
59eeeb3
Update lib
antonis Dec 3, 2024
8814472
Launch AppReadyActivity manually for testing
antonis Dec 3, 2024
b6e603d
Merge branch 'main' into antonis/3413-android-app-start-metric
antonis Dec 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
- name: Collect apps metrics
uses: getsentry/action-app-sdk-overhead-metrics@v1
uses: antonis/action-app-sdk-overhead-metrics@67d7579b9398ac756bcf2cd5693782ca4b02a92f
with:
name: ${{ matrix.name }} (${{ matrix.rn-architecture }})
config: ./performance-tests/metrics-${{ matrix.platform }}.yml
Expand Down
11 changes: 10 additions & 1 deletion performance-tests/TestAppPlain/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* @flow strict-local
*/

import React from 'react';
import React, { useEffect } from 'react';
import { NativeModules } from 'react-native';
import type {Node} from 'react';
import {
SafeAreaView,
Expand Down Expand Up @@ -52,7 +53,15 @@ const Section = ({children, title}): Node => {
);
};

const { ActivityStarter } = NativeModules;

const App: () => Node = () => {
useEffect(() => {
if (Platform.OS === 'android') {
ActivityStarter.startAppReadyActivity();
}
}, []);

const isDarkMode = useColorScheme() === 'dark';

const backgroundStyle = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AppReadyActivity" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.testappplain;

import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class AppReadyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Add a simple text saying that the app is fully loaded
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
layout.setGravity(Gravity.CENTER);
TextView textView = new TextView(this);
textView.setText("The App is fully loaded!\nTap/swipe back to close this view.");
textView.setTextSize(24);
textView.setGravity(Gravity.CENTER);
layout.addView(textView);
setContentView(layout);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.testappplain;

import android.content.Intent;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class AppReadyModule extends ReactContextBaseJavaModule {

private final ReactApplicationContext reactContext;

public AppReadyModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@Override
public String getName() {
return "ActivityStarter";
}

@ReactMethod
public void startAppReadyActivity() {
Intent intent = new Intent(reactContext, AppReadyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
reactContext.startActivity(intent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ protected String getMainComponentName() {
return "TestAppPlain";
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Intent intent = new Intent(this, AppReadyActivity.class);
startActivity(intent);
}

/**
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import com.testappplain.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
Expand All @@ -22,12 +27,24 @@ public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

ReactPackage appReadyPackage =
new ReactPackage() {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new AppReadyModule(reactContext));
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
};

@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(appReadyPackage);
return packages;
}

Expand Down
11 changes: 10 additions & 1 deletion performance-tests/TestAppSentry/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* @flow strict-local
*/

import React from 'react';
import React, { useEffect } from 'react';
import { NativeModules } from 'react-native';
import type {Node} from 'react';
import {
SafeAreaView,
Expand Down Expand Up @@ -58,7 +59,15 @@ const Section = ({children, title}): Node => {
);
};

const { ActivityStarter } = NativeModules;

const App: () => Node = () => {
useEffect(() => {
if (Platform.OS === 'android') {
ActivityStarter.startAppReadyActivity();
}
}, []);

const isDarkMode = useColorScheme() === 'dark';

const backgroundStyle = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AppReadyActivity" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.testappsentry;

import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

public class AppReadyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Add a simple text saying that the app is fully loaded
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
layout.setGravity(Gravity.CENTER);
TextView textView = new TextView(this);
textView.setText("The App is fully loaded!\nTap/swipe back to close this view.");
textView.setTextSize(24);
textView.setGravity(Gravity.CENTER);
layout.addView(textView);
setContentView(layout);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.testappsentry;

import android.content.Intent;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class AppReadyModule extends ReactContextBaseJavaModule {

private final ReactApplicationContext reactContext;

public AppReadyModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@Override
public String getName() {
return "ActivityStarter";
}

@ReactMethod
public void startAppReadyActivity() {
Intent intent = new Intent(reactContext, AppReadyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
reactContext.startActivity(intent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import com.testappsentry.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {
Expand All @@ -22,12 +27,24 @@ public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

ReactPackage appReadyPackage =
new ReactPackage() {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new AppReadyModule(reactContext));
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
};

@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(appReadyPackage);
return packages;
}

Expand Down
4 changes: 3 additions & 1 deletion performance-tests/metrics-android.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
apps:
- name: com.testappplain
activity: MainActivity
measureActivity: AppReadyActivity
path: TestAppPlain/android/app/build/outputs/apk/release/app-release.apk
- name: com.testappsentry
activity: MainActivity
measureActivity: AppReadyActivity
path: TestAppSentry/android/app/build/outputs/apk/release/app-release.apk

startupTimeTest:
runs: 50
diffMin: -20
diffMin: 0
diffMax: 150

binarySizeTest:
Expand Down
Loading