Preloading React Native bridge (Android)

William Liu
2 min readNov 6, 2016

--

Loading speed is crucial to many RN apps. Developers want to speed up the loading of the RN app as much as possible. One way to speed up loading is to preload the bridge before launching the RN app. I won’t discuss it in details here. You can read this post for more details.

Solution

The solution is to preload the React Context in the main activity before launching the RN app in a different activity.

My experiment shows that preloading on a Nexus 5 device can save about 60% to 70% of the RN loading time (excluding the network requests)

Here is the sample code. Call it from the main activity before launching the RN activity to preload the bridge (if you use a different activity to host RN app.)

mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
//.setUseOldBridge(true) // uncomment this line if your app crashes
.build();
mReactInstanceManager.createReactContextInBackground();

If you are interested in the createReactContextInBackground() method, you can look at the interface here.

There is a bug

The above code has a bug — the current activity in the context is null in the native modules. For example, I have the following react native module in the MainReactPackage.

public class MyModule extends ReactContextBaseJavaModule {
private void doSomething() {
Activity activity = getCurrentActivity(); // activity is null!!
// do something with the activity
}
}

What is wrong?

Looking at XReactInstanceManagerImpl.onHostResume, it calls moveToResumedLifecycleState(false). In moveToResumedLifecycleState, the code looks like this.

if (force ||
mLifecycleState == LifecycleState.BEFORE_RESUME ||
mLifecycleState == LifecycleState.BEFORE_CREATE) {
mCurrentReactContext.onHostResume(mCurrentActivity);
}

Therefore, if it initialize lifecycle to LifecycleState.RESUMED, onHostResume will not update the current activity in the react context.

To fix it, initialize lifecycle state to BEFORE_RESUMED.

.setInitialLifecycleState(LifecycleState.BEFORE_RESUMED)

Now when the activity that hosts the React Native app resumes, it will set the current react context. Problem solved and you have a much more performant RN app!

--

--