Tempted to abandon React Native for native Android Part 2

My post about some issues I was having with the performance of images in React Native received quite a bit of attention. As developers, we’re all concerned about how well our code does its job. The response was unexpected but tremendously appreciated. The responses helped to give me some insight into the cause of the problem and potential solutions. This, for me, is what makes the internet so great.

The first order of business was to test my hypothesis that a native Android app would perform better in the way in which images are handled. I created an app in Android Studio and added code to select an image via an intent and display it in an ImageView. The first attempt was with an Android Marshmallow device with 1.5 GB of RAM. I selected a random image that turned out to be pretty big and it didn’t display. I caught in the logcat output that it failed because it was too big. The limit for an image that could be displayed was around 5000×4000 pixels.

I then tried the specific image that was crashing the original React Native app. It opened without problems. I took this as evidence that a native app generally handles images better but would still have problems with large images, so resizing images is probably something that should be done irrespective of the toolset.

In the Hacker News comments someone alluded to the problem by saying that it is never efficient to be passing large amounts of data via intents. At the time, I wasn’t sure that was the issue because I was thinking that the only data being passed through the intent was a link to the image and not the image itself.

However, another person mentioned base64 data and I remembered that base64 data was being passed as well. With that realization, I was eager to test it out. I looked up the documentation for the image picker that I was using and noticed that there were many options that I had glossed over. There was an option to not return base64 data and also options to resize the image. This could have saved me the trouble of an extra resizing component.

In trying to diagnose the problem, I implemented two different strategies for selecting an image. The first was via intent which loads the Gallery app and allows the user to select the image. I set the option to resize the image to 300×200 pixels and not return the base64 data. The app still crashed on most of the images I tried.

Suspecting that having to switch apps might be an issue, the second technique was to load the images directly within the app. This was done using a pure JavaScript component based on the Camera Roll API. This technique caused crashes with large images, but with the images resized to 300×200, they loaded without issue.

So it appears that there is still something going on when the React Native app switches to the Gallery app via the image picker. It may have something to do with the fact that the module has to resize the image and that may be what’s using up the limited memory on the 512MB Kit Kat device.

That’s left to be confirmed but for the time being, I am happy with what this experience has taught me. It appears that the problem is partially my fault as I was not handling the images efficiently from my end in the first place, so I offer my apology to React Native if I misrepresented it!

I have not given up on React Native but I am still determined to explore native Android further. That may be a topic for another post.

2 Replies to “Tempted to abandon React Native for native Android Part 2”

Leave a Reply