visit
These last few days, I had a chance to focus on improving the performances of the React Native app we build in our company: being already on both markets (iOS/Android), the approach I took was mainly JS-focused, in order to be able to deploy the tweaks via Microsoft’s tool.
I have to admit, I was quite surprised by how effective some of these changes have been — and this is why I’m sharing them with you all, hoping to help you understand that improving performances can be simple; not something that only the hardcore veterans can manage to pull off, as I used to think prior to this past week.
Within the react-native
base project there is a benchmarking tool calledPerfMonitor
. From my understanding, this is basically the same standard React Perf tool — which you can read more about . Basically it provides you with an analysis of how much time (in ms) your app is wasting in useless re-renders; it has one flaw though, which is that it can only run in debugger mode, which is not optimised.
I can’t go into the details of our app architecture, but what I think you should know is that the mentioned Logged component contains the main navigation tab bar (composed of 4 tabs) and that the first main tab contains its own tab bar navigation, again with 4 tabs (one of which uses Airbnb’s component).(and yeah, we use )
The actual starting point This was the baseline I worked with: before applying any sort of optimisation, this is what the Perf tool provided as benchmark.
We obtained a good ~50ms per Component improvement in the top 10 (with only a couple of exceptions, like CellRenderer). Good, but nothing major — so I kept digging.
Since some of our components have huge lists of items to show (like most apps), we need to react to props’ changes in specific ways. One of the checks we did in our componentWillReceiveProps was made on the list’s dataset, and when we changed the array comparison from the standard === to _.isEqual() method, this is what happened:
This has been one of the most effective optimisation: apparently the lodash method is way better for comparing arrays — or maybe I’m just a noob and it was know by everyone except me 😇
It won’t surprise anyone knowing that the app communicates constantly with a backend, which provides most data that needs to be shown throughout the whole app. Turns out that, during all my tweaking and fixing and being excited about performance improvements… our backend was not fully working 👾 So, just when I was about to run the last benchmark, my boss pinged me over Slack to let me know that he fixed a bug on the backend, and that finally the pins in the Map were showing again.REALITY. STRUCK. BACK.
Oh, no…I run the benchmark.
My reaction #truefact Having (again) the map full of pins created a whole the new level of wasted ms.
(small disclaimer: don’t consider this a rant towards those devs who created & maintain the Map component, ok!? Those huge numbers are surely caused by my inexperience)So, basically, I was back to square 1… but I couldn’t stop now, I was so close to performance heaven!
We got some improvements, again. Not enough though… time for one last try 💪
By changing the logic in the render()
method for the tabMap, I managed to have the pins&markers loaded only when the component is actually “shown” — the code is something similar to:
This last improvement managed to get us “back to good performances”, considering that all these measurements are over a 20000 ms timespan:
I was finally satisfied with the improvements: once we codepushed them to staging, the difference in the release version of the ⚛️ app was perceivable.
this MAY have been my boss reaction
A lot more can surely be done: I’m no JS expert, and surely would be able to code the performances up a lot more (if you haven’t ever heard of him or read his articles on React Native performances, go NOW) — but, hey, still got some solid results 😊
I seriously hope that this article may help you out with your own React Native apps, and that there are no major mistakes in what I’ve written above.In that sense, I’m really looking forward your feedback and/or suggestions: feel free to leave a comment or tweet and I’ll be happy to talk with y’all 🤓
And, as always,
Happy coding! 🤖