As advised in the docs, I moved some long data-fetching code into a native module to free the JS thread, but I observe that this is still blocking the UI. Why is that and what can I do to avoid that ?
The native module is called from JS as so :
MyNativeModule.fetch(path).then( data => dispatchData(data) )
The native method looks like this (it uses the Android Firebase SDK):
@ReactMethod
public void fetch(final String path, final Promise promise) {
root.child(path).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
promise.resolve(castSnapshot(snapshot));
} else {
promise.resolve(null);
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
promise.reject(firebaseError.getMessage());
}
}
}
The castSnapshot
method converts the Firebase DataSnapshot
object into a WriteableMap
. I can share the implementation if that is useful.
What I observed is that even if I replace promise.resolve(castSnapshot(snapshot));
by castSnapshot(snapshot); promise.resolve(null);
, the call is blocking the UI : so it is not sending the data over the bridge that is the culprit. If the amount of data is large, castSnapshot
can take some time, and this is clearly what is blocking.
Even if this code is long running, shouldn't moving it to a native module free the UI? What do I not get about this?
Many thanks.
What are Native UI components in React Native? Under the hood, React Native uses native components like UIView and UIImageView in iOS and exports them to the JavaScript layer. We use these components in our daily development process.
Then, under the hood, the React Native “bridge” invokes the native rendering APIs in Objective-C (for iOS) or Java (for Android). Thus, your application will render using real mobile UI components, not webviews, and will look and feel like any other mobile application.
UI thread (often called main): The only thread that can manipulate host views. JavaScript thread: This is where React's render phase is executed. Background thread: Thread dedicated to layout.
Try wrapping the root.child
line in a new Thread instance, like this:
@ReactMethod
public void fetch(final String path, final Promise promise) {
new Thread(new Runnable() {
public void run() {
root.child(path)...
}
}).start();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With