Add perf markers for cold start

Summary: public

Adds useful systrace perf markers for cold start analysis

Reviewed By: mikearmstrong001

Differential Revision: D2695629

fb-gh-sync-id: d964f28a1f3e10a13c441a17b0300c980d4914e8
This commit is contained in:
Andy Street
2015-11-25 04:56:15 -08:00
committed by facebook-github-bot-0
parent 388d8c8f9b
commit ca016e4eb3
5 changed files with 147 additions and 56 deletions

View File

@@ -32,6 +32,7 @@ import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.debug.DebugComponentOwnershipModule; import com.facebook.react.uimanager.debug.DebugComponentOwnershipModule;
import com.facebook.react.uimanager.events.RCTEventEmitter; import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.systrace.Systrace;
/** /**
* Package defining core framework modules (e.g. UIManager). It should be used for modules that * Package defining core framework modules (e.g. UIManager). It should be used for modules that
@@ -53,6 +54,16 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
@Override @Override
public List<NativeModule> createNativeModules( public List<NativeModule> createNativeModules(
ReactApplicationContext catalystApplicationContext) { ReactApplicationContext catalystApplicationContext) {
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createUIManagerModule");
UIManagerModule uiManagerModule;
try {
uiManagerModule = new UIManagerModule(
catalystApplicationContext,
mReactInstanceManager.createAllViewManagers(catalystApplicationContext));
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
return Arrays.<NativeModule>asList( return Arrays.<NativeModule>asList(
new AnimationsDebugModule( new AnimationsDebugModule(
catalystApplicationContext, catalystApplicationContext,
@@ -64,9 +75,7 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
new SourceCodeModule( new SourceCodeModule(
mReactInstanceManager.getSourceUrl(), mReactInstanceManager.getSourceUrl(),
mReactInstanceManager.getDevSupportManager().getSourceMapUrl()), mReactInstanceManager.getDevSupportManager().getSourceMapUrl()),
new UIManagerModule( uiManagerModule,
catalystApplicationContext,
mReactInstanceManager.createAllViewManagers(catalystApplicationContext)),
new DebugComponentOwnershipModule(catalystApplicationContext)); new DebugComponentOwnershipModule(catalystApplicationContext));
} }

View File

@@ -55,6 +55,7 @@ import com.facebook.react.uimanager.ReactNative;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
import com.facebook.systrace.Systrace;
/** /**
* This class is managing instances of {@link CatalystInstance}. It expose a way to configure * This class is managing instances of {@link CatalystInstance}. It expose a way to configure
@@ -465,11 +466,16 @@ import com.facebook.soloader.SoLoader;
@Override @Override
public List<ViewManager> createAllViewManagers( public List<ViewManager> createAllViewManagers(
ReactApplicationContext catalystApplicationContext) { ReactApplicationContext catalystApplicationContext) {
List<ViewManager> allViewManagers = new ArrayList<>(); Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createAllViewManagers");
for (ReactPackage reactPackage : mPackages) { try {
allViewManagers.addAll(reactPackage.createViewManagers(catalystApplicationContext)); List<ViewManager> allViewManagers = new ArrayList<>();
for (ReactPackage reactPackage : mPackages) {
allViewManagers.addAll(reactPackage.createViewManagers(catalystApplicationContext));
}
return allViewManagers;
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} }
return allViewManagers;
} }
@VisibleForTesting @VisibleForTesting
@@ -586,30 +592,73 @@ import com.facebook.soloader.SoLoader;
reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager); reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager);
} }
CoreModulesPackage coreModulesPackage = Systrace.beginSection(
new CoreModulesPackage(this, mBackBtnHandler); Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); "createAndProcessCoreModulesPackage");
try {
CoreModulesPackage coreModulesPackage =
new CoreModulesPackage(this, mBackBtnHandler);
processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
// TODO(6818138): Solve use-case of native/js modules overriding // TODO(6818138): Solve use-case of native/js modules overriding
for (ReactPackage reactPackage : mPackages) { for (ReactPackage reactPackage : mPackages) {
processPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"createAndProcessCustomReactPackage");
try {
processPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
}
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "buildNativeModuleRegistry");
NativeModuleRegistry nativeModuleRegistry;
try {
nativeModuleRegistry = nativeRegistryBuilder.build();
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "buildJSModuleConfig");
JavaScriptModulesConfig javaScriptModulesConfig;
try {
javaScriptModulesConfig = jsModulesBuilder.build();
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} }
CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder() CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
.setCatalystQueueConfigurationSpec(CatalystQueueConfigurationSpec.createDefault()) .setCatalystQueueConfigurationSpec(CatalystQueueConfigurationSpec.createDefault())
.setJSExecutor(jsExecutor) .setJSExecutor(jsExecutor)
.setRegistry(nativeRegistryBuilder.build()) .setRegistry(nativeModuleRegistry)
.setJSModulesConfig(jsModulesBuilder.build()) .setJSModulesConfig(javaScriptModulesConfig)
.setJSBundleLoader(jsBundleLoader) .setJSBundleLoader(jsBundleLoader)
.setNativeModuleCallExceptionHandler(mDevSupportManager); .setNativeModuleCallExceptionHandler(mDevSupportManager);
CatalystInstance catalystInstance = catalystInstanceBuilder.build(); Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createCatalystInstance");
CatalystInstance catalystInstance;
try {
catalystInstance = catalystInstanceBuilder.build();
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
if (mBridgeIdleDebugListener != null) { if (mBridgeIdleDebugListener != null) {
catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener); catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);
} }
reactContext.initializeWithInstance(catalystInstance); reactContext.initializeWithInstance(catalystInstance);
catalystInstance.runJSBundle();
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "runJSBundle");
try {
catalystInstance.runJSBundle();
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
return reactContext; return reactContext;
} }

View File

@@ -88,8 +88,13 @@ public class CatalystInstanceImpl implements CatalystInstance {
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
initializeBridge(jsExecutor, jsModulesConfig); Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "initializeBridge");
initLatch.countDown(); try {
initializeBridge(jsExecutor, jsModulesConfig);
initLatch.countDown();
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
} }
}); });
@@ -108,22 +113,31 @@ public class CatalystInstanceImpl implements CatalystInstance {
mCatalystQueueConfiguration.getJSQueueThread().assertIsOnThread(); mCatalystQueueConfiguration.getJSQueueThread().assertIsOnThread();
Assertions.assertCondition(mBridge == null, "initializeBridge should be called once"); Assertions.assertCondition(mBridge == null, "initializeBridge should be called once");
mBridge = new ReactBridge( Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ReactBridgeCtor");
jsExecutor, try {
new NativeModulesReactCallback(), mBridge = new ReactBridge(
mCatalystQueueConfiguration.getNativeModulesQueueThread()); jsExecutor,
mBridge.setGlobalVariable( new NativeModulesReactCallback(),
"__fbBatchedBridgeConfig", mCatalystQueueConfiguration.getNativeModulesQueueThread());
buildModulesConfigJSONProperty(mJavaRegistry, jsModulesConfig)); } finally {
Systrace.registerListener(mTraceListener); Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "setBatchedBridgeConfig");
try {
mBridge.setGlobalVariable(
"__fbBatchedBridgeConfig",
buildModulesConfigJSONProperty(mJavaRegistry, jsModulesConfig));
mBridge.setGlobalVariable(
"__RCTProfileIsProfiling",
Systrace.isTracing(Systrace.TRACE_TAG_REACT_APPS) ? "true" : "false");
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
} }
@Override @Override
public void runJSBundle() { public void runJSBundle() {
Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"CatalystInstance_runJSBundle");
try { try {
final CountDownLatch initLatch = new CountDownLatch(1); final CountDownLatch initLatch = new CountDownLatch(1);
mCatalystQueueConfiguration.getJSQueueThread().runOnQueue( mCatalystQueueConfiguration.getJSQueueThread().runOnQueue(
@@ -135,10 +149,16 @@ public class CatalystInstanceImpl implements CatalystInstance {
incrementPendingJSCalls(); incrementPendingJSCalls();
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "loadJSScript");
try { try {
mJSBundleLoader.loadScript(mBridge); mJSBundleLoader.loadScript(mBridge);
// This is registered after JS starts since it makes a JS call
Systrace.registerListener(mTraceListener);
} catch (JSExecutionException e) { } catch (JSExecutionException e) {
mNativeModuleCallExceptionHandler.handleException(e); mNativeModuleCallExceptionHandler.handleException(e);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} }
initLatch.countDown(); initLatch.countDown();
@@ -149,8 +169,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
"Timed out loading JS!"); "Timed out loading JS!");
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} }
} }

View File

@@ -13,7 +13,6 @@ import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -186,32 +185,38 @@ public class NativeModuleRegistry {
} }
public NativeModuleRegistry build() { public NativeModuleRegistry build() {
JsonFactory jsonFactory = new JsonFactory(); Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateJSON");
StringWriter writer = new StringWriter(); String moduleDefinitionJson;
try { try {
JsonGenerator jg = jsonFactory.createGenerator(writer); JsonFactory jsonFactory = new JsonFactory();
jg.writeStartObject(); StringWriter writer = new StringWriter();
for (ModuleDefinition module : mModuleDefinitions) { try {
jg.writeObjectFieldStart(module.name); JsonGenerator jg = jsonFactory.createGenerator(writer);
jg.writeNumberField("moduleID", module.id); jg.writeStartObject();
jg.writeObjectFieldStart("methods"); for (ModuleDefinition module : mModuleDefinitions) {
for (int i = 0; i < module.methods.size(); i++) { jg.writeObjectFieldStart(module.name);
MethodRegistration method = module.methods.get(i); jg.writeNumberField("moduleID", module.id);
jg.writeObjectFieldStart(method.name); jg.writeObjectFieldStart("methods");
jg.writeNumberField("methodID", i); for (int i = 0; i < module.methods.size(); i++) {
jg.writeStringField("type", method.method.getType()); MethodRegistration method = module.methods.get(i);
jg.writeObjectFieldStart(method.name);
jg.writeNumberField("methodID", i);
jg.writeStringField("type", method.method.getType());
jg.writeEndObject();
}
jg.writeEndObject();
module.target.writeConstantsField(jg, "constants");
jg.writeEndObject(); jg.writeEndObject();
} }
jg.writeEndObject(); jg.writeEndObject();
module.target.writeConstantsField(jg, "constants"); jg.close();
jg.writeEndObject(); } catch (IOException ioe) {
throw new RuntimeException("Unable to serialize Java module configuration", ioe);
} }
jg.writeEndObject(); moduleDefinitionJson = writer.getBuffer().toString();
jg.close(); } finally {
} catch (IOException ioe) { Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
throw new RuntimeException("Unable to serialize Java module configuration", ioe);
} }
String moduleDefinitionJson = writer.getBuffer().toString();
return new NativeModuleRegistry(mModuleDefinitions, mModuleInstances, moduleDefinitionJson); return new NativeModuleRegistry(mModuleDefinitions, mModuleInstances, moduleDefinitionJson);
} }
} }

View File

@@ -106,10 +106,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
mShadowNodeRegistry); mShadowNodeRegistry);
DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics(); DisplayMetrics displayMetrics = reactContext.getResources().getDisplayMetrics();
DisplayMetricsHolder.setDisplayMetrics(displayMetrics); DisplayMetricsHolder.setDisplayMetrics(displayMetrics);
mModuleConstants = createConstants(displayMetrics, viewManagerList);
mModuleConstants = UIManagerModuleConstantsHelper.createConstants(
displayMetrics,
viewManagerList);
reactContext.addLifecycleEventListener(this); reactContext.addLifecycleEventListener(this);
} }
@@ -143,6 +140,19 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
mEventDispatcher.onCatalystInstanceDestroyed(); mEventDispatcher.onCatalystInstanceDestroyed();
} }
private static Map<String, Object> createConstants(
DisplayMetrics displayMetrics,
List<ViewManager> viewManagerList) {
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateUIManagerConstants");
try {
return UIManagerModuleConstantsHelper.createConstants(
displayMetrics,
viewManagerList);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
}
/** /**
* Registers a new root view. JS can use the returned tag with manageChildren to add/remove * Registers a new root view. JS can use the returned tag with manageChildren to add/remove
* children to this view. * children to this view.