@Override public void onCreate() { super.onCreate(); ///////// Add lines below this to capture times of the large sections final String TAG = "RN_STARTUP"; // If you already have a TAG for the app, use that instead. final TimingLogger timingLogger = new TimingLogger("AXE", "REACT_NATIVE_STARTUP"); timingLogger.reset(); ReactMarker.addListener(new ReactMarker.MarkerListener() { @Override public void logMarker(ReactMarkerConstants constant, @Nullable String tag, int instanceKey) { StringBuilder message = new StringBuilder(constant.toString()).append(" ").append(tag).append(" ").append(instanceKey); // While we log these in ADB logcat, you should ideally also log these from production. // That way, you will more accurate timings from real devices. You can cross reference this with device types too ! // Basically, just save the timestamps to a list, and then upload the times to your server in the next method. //Also note that the markers have a _START and an _END, so you could even log timespans, instead of just timestamps Log.i("REACT_NATIVE_STARTUP", message.toString()); timingLogger.addSplit(message.toString()); } }); // This should not be just a simple handler, but should be invoked after your "Load" event. The "Load" event itself is // different for different apps - some define it as the time a first screen is displayed, for others, it is defined as when // a network request returns with data and all of that is rendered. // For now, we can live with a 10second delay, will talk more about the actual end of a "Load" event in a subsequent post. new Handler().postDelayed(new Runnable() { @Override public void run() { // During development, you will see this in ADB logcat. Just ensure that you run // adb shell setprop log.tag.RN_STARTUP VERBOSE on the terminal, before running adb logcat // This is where you would upload all the timespans to a server, so that you can aggregate them timingLogger.dumpToLog(); } }, 10000); /////////////////// End of snippet SoLoader.init(this, /* native exopackage */ false); }