Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this call to a react-native native module blocking the UI?

Tags:

react-native

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.

like image 671
VonD Avatar asked Mar 31 '16 10:03

VonD


People also ask

Does React Native use native UI?

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.

How does React Native works under the hood?

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.

What is UI thread React Native?

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.


1 Answers

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();
}
like image 85
Ryan H. Avatar answered Oct 06 '22 00:10

Ryan H.