Debugging RN Android Performance

Bookmark

You want to know if your RN app has the best performance? Check out the slow rendering UI stat on the play store, if your numbers are not so good, come to this talk! I will present Systrace, a tool that can be daunting to use at first glance, but a fantastic tool, once you learn how to master it. I will show how it helped us detect and solve performance issues in our app.



Transcription


Hi, everyone. I'm Alex. I'm excited to talk to you at react Summit. I'm a tech lead at BAM. We're a company based in Paris. We develop mobile apps in Kotlin, Swift, Flutter, and of course react Native. And today I want to talk to you about the performance of react Native apps. Now, one of the key metrics to analyze the performance of your app is the frame rate. You want your app to run at 60 frames per second. One of the good things that come with react Native out of the box is this tool, the performance monitor. You get actually the frame rate of the UI thread and also of the JS thread. So now one of the issues we're facing in our app is the UI thread rate was consistently low after starting the app, even when the user was doing absolutely nothing. The question was how to find out what is actually happening under the hood. And the solution to that was Systrace. Systrace is short for system trace. It's available out of the box on the Android SDK in the platform tools folder. Essentially it's a script. So you can connect your app to the computer and you just start the script. You do some stuff on your app. You stop the script and it will print out a huge html file, a trace file. You can open that file in Chrome. And when you open it, it looks like this. Wow. It is daunting, right? Very colorful, but quite daunting. So the first thing you want to do is on the left side, you want to find your app. Hi, everyone. I'm Alex. I'm excited to talk to you at react Summit. I'm a tech lead at BAM. We're a company based in Paris. We develop mobile apps in Kotlin, Swift, Flutter, and of course react Native. And today I want to talk to you about the performance of react Native apps. Now, one of the key metrics to analyze the performance of your app is the frame rate. You want your app to run at 60 frames per second. One of the good things that come with react Native out of the box is this tool, the performance monitor. You get actually the frame rate of the UI thread and also of the JS thread. So now one of the issues we're facing in our app is the UI thread rate was consistently low after starting the app, even when the user was doing absolutely nothing. The question was how to find out what is actually happening under the hood. And the solution to that was Systrace. Systrace is short for system trace. It's available out of the box on the Android SDK in the platform tools folder. Essentially it's a script. So you can connect your app to the computer and you just start the script. You do some stuff on your app. You stop the script and it will print out a huge html file, a trace file. You can open that file in Chrome. And when you open it, it looks like this. Wow. It is daunting, right? Very colorful, but quite daunting. So the first thing you want to do is on the left side, you want to find your app.

In my case, my bundle ID was myapp.debug. So this is where I found it. And then below it, since we're talking about frame rates, what is really interesting is the frames line. So if you zoom in a little bit on the frames line, you will notice a lot of Fs. There are red Fs, yellow Fs, and green Fs. You might guess that a red F is bad and a green F is good. Indeed, a green F is actually a frame that was able to be calculated under 16 milliseconds that the app can actually run at 60 frames per second. Yellow Fs and red Fs, not so much. So if you're trying to analyze performance issues, you want to take a look at sources of red Fs and yellow Fs.

In our app, we actually had two major sources of red Fs. Let's take a look at the first one. If we zoom in on a single frame, so this is about 20 milliseconds of time, and we can see our friend, the UI of the app. So this is what was actually reported in the performance monitor. We can see that actually on a single frame, it's doing a lot of calculations. So it's not able to fit in the 16 milliseconds set of time. So now the question is, what is it actually doing? So we can take a look. We can actually click inside and we can see a bit more details, but it's very low level. For example, we see that we have a draw function that is taking a lot of time, but this is the OS basically redrawing stuff. So something is actually needed to be redrawn and it takes a lot of time, but we don't really know what it is.

We can actually scroll down a little bit and find the render thread. The render thread is running on the GPU and it runs expensive calculation on the GPU. And on this one, we're a bit luckier because see here, we have actually something about Lottie animation view. Now, Lottie is an animation framework and we actually had a Lottie animation at the start of our app. And we found out that it needed to be optimized and that was the performance issue. So that's one performance issue solved, one issue to go.

Let's look at the second one. So the second one was happening near the end of the trace file. Can see lots and lots of red Fs here. And this was actually when the user was doing nothing at all. So this was very intriguing. If we zoom in like before on frames, we can see that a lot of stuff happens on the UI thread and the render thread. They're really busy with calculations, but we're not so lucky as before because all of the tasks seem to be very low level. We can't really get what is actually happening. We know that something expensive needs to be redrawn every time, but we don't really know what it is. Okay. What can we do? Well, we can take a look at what's up there. If we scroll up a little bit, the CPU section, the CPU section is quite interesting. You can see at any given set of time, watch each of the CPU is actually running for your app on your device. For example, if we zoom in, we can see that in this set of time, CPU four was running MQT JS. That's the JS thread. And this one was running Fresco, which is handling images because Fresco is a library used to handle images on react Native. So now in this set of time, what is actually happening? The nice thing with Systrace is you can actually draw a rectangle, a big selection over everything that is happening in the set of time on the CPU. And on the bottom part, you will see basically all of the tasks that have been run. And if you click on wall duration here, you can sort the task by what was the task that took actually the most CPU time. And here, the top one is render thread. Well, we knew that already, the render thread was doing some expensive stuff, but we didn't really know what it was. The second one was quite interesting though, because it's called Chrome in Procre. And a quick search, and we realized that this was related to web views. So we thought, what web views do we have? And it turns out we actually have ads running at the start of our app. And those ads are running in web view.

And they also needed to be optimized. So that was our second source of performance issue.

And now, once those were solved, just green apps everywhere. Much better, right?

So that's it. I hope you learned a lot of things, and feel free to hit me up with questions. Thank you for watching.

7 min
14 May, 2021

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic