7 common performance issues that can occur in your app

Illustration by Justyna Mieleszko

They can be seen right at first sight, after some time or on specific kind of devices. In the post below, I will share my thoughts on the most common problems with app performance, ways those issues can undermine your work and the easiest way to solve them.

1. Memory leaks when subscriptions in RxJava are not cleared

They occur when an object in memory is not deleted, even if it is no longer needed. In RxJava, a popular library in Android ecosystem, it often happens when users don’t clear their subscriptions correctly.
When subscribing to the Observable an anonymous class is created, which always keep reference to their calling class. In result, if you don’t clear subscription, an anonymous class will keep outer class instance and all variables that you used inside them.
Fortunately, there is a simple solution to avoid this problem. All you need to do is create CompositeSubscription and then clear it after it is no longer needed.

2. Not unsubscribing from sensor listeners

When you are registering a new sensor listener, you need to pass the Context as a service listener. If you forget to unregister it, it will keep Activity instance even after it’s no longer necessary for creating a memory leak.
One of the best ways to help you notice memory leaks is using the LeakCanary library. It will notify you anytime it notices your memory is not released when it should be.

3. Adding inappropriate resources

In general, I recommend using vector drawables wherever possible. It has, theoretically, a slightly higher performance impact, but it reduces overall apk size and leaves image scaling to the system. Sometimes with performance-sensitive jobs you will need bitmaps. When using png drawables you should always use the appropriate resource dimension. You should remember then about no-dpi dimension. These resources won’t be scaled at all.
At Indoorway we had a problem with a map background once. Firstly, we put it in the folder with scaled resource and then we tried to scale it according to the user’s needs. In result, the map was scaled twice and it shuttered.

4. Keeping too big images

Beginners often keep too big images. Usually you see a list of thumbnails which enlarge to full view after clicking. At the beginning people often download images, put them into the list view, then let them resize. That way we are downloading a full sized image and keep it in memory.

A better approach is to use a library like Picasso and scale images on flight. That way you store only a thumbnail. It loads to full image after a click.
Here you’ll find a Google’s video that should help you with more complicated problems:

5. Performing resource-exhausting tasks too often

Every app profiling you should start by looking at components that take time to process. We are often doing monotonous computing heavy work in background when we could just cache the result for future use, or we repeatedly load something that could be stored in memory.
The best tool to deal with such problem is Android Profiler. Take a look at the methods that are the computational heaviest and then start your work from there.

In my next article I’ll show an example of how to find these problematic parts in your code with Android Profiler.

6. Testing always on high-end device

Many issues, not only performance-related, can be noticed only on slower devices. For example, a process, that is fast on Galaxy S9 can be really bothering to user with the old Motorola. Of course, you should always remember to test your app on devices, that your users will own in the future, just don’t forget that many people worldwide do not have the latest models of phones and you should keep them happy as well.

7. Performance is relevant

The last advice is to keep in mind that performance is relevant to the user. Make sure your app is responsive and gives proper feedback. People like to know what is going on. They prefer to be informed about the level of progression (you can show it with a simple progress bar) rather than be surprised after a while with the app freeze or worse — the ANR dialog. Even if the app needs time to complete some processes in background, keep your users informed and they will be more forgiving.

As you can see, there are many performance-related aspects that you should keep in mind while working on the app. At first, those issues can be unnoticable but after some time they accumulate and can be problematic to the users. Hopefully, after reading this article you already become aware of the most common problems. In the next post I’ll show you how to detect some more sneaky leaks with memory profiler.

--

--