Why does an Android App lag?
- Amit Shekhar
- Published on
I am Amit Shekhar, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.
Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out Android Interview Questions and Answers.
In this blog, we will learn why an Android App lags. I believe that every Android Developer should know the reason for the low performance of the Android app.
I will start with the following statement:
Garbage Collector: The TAX on Android App Performance
The main reason for the Android App lag or for the low performance of the Android app is that it runs GC very frequently.
Simple in one line: The time for which GC is running the actual app is not running.
Basically, when the Android App runs, it allocates many objects on the basis of your code, and when the objects are no longer referred to, the system calls GC when there is memory pressure to deallocate those objects.
So, if the object allocation and deallocation occur on the regular basis, it means that the GC will run on a regular basis to release memory.
Here, the important point is that the time for which the GC runs, your app does not run for that time. So, it seems that the app is lagging. And hence, a bad experience for the user of the application. Let's understand it deeply.
The Android app updates its UI every
60FPS -> 1000ms/60 = 16.67ms ~ 16ms) for smooth UI rendering.
Frame per second (FPS) is the measurement of the number of frames that appear within a second.
So, if the GC runs for more time, the app will be unable to update UI and it will skip a few frames, so it will seem that the app is lagging. That is one of the reasons for the app lag.
Another reason is that the app is doing too much on the main thread. For example, at that time if any method/task is taking more time than
16ms, the app will be unable to update UI, which means lag will be there in the app for that time.
Basically, the system tries to redraw the UI every
16ms, and what if our task on the main thread takes more than
16ms? For example, if our task takes
26ms. The system tries to update the UI, but it wasn't ready. In that case, it will not refresh anything. And, that caused the UI to be refreshed after
32ms instead of
16ms. Ultimately, there will be a frame drop.
So, due to the frame drop, the user finds the app laggy.
Even if there is one dropped frame, the animation will not be smooth. The user will find it laggy.
Now, we have understood the two most important reasons because of why the Android Apps lag which are as follows:
- GC running frequently
- Doing too much work on the main thread
In order to fix this lag issue, we need to focus on the following:
- Reduce GC running time
- Do not do too much on the main thread
Steps to be taken to improve the performance:
- Do not allocate any object if it is not required. Do not allocate objects early, allocate objects only when it is required. Use lazy initialization.
- Avoid Auto-Boxing as Integer, Boolean, etc takes more memory as classes like
Integertakes more memory so use
intwhere ever possible instead of
- Use ArrayMap and SparseArray. Refer to this article, this will show why and when to use ArrayMap and SparseArray to optimize your Android Applications.
- Use the concept of object pools to avoid memory churn. Learn about the bitmap pool.
- Keep heavy work away from the main thread. Transfer it to the background thread.
- Use static final for constants or const val in Kotlin.
- Avoid Internal Getters/Setters wherever not necessary (direct field access is 3x faster)
- Don't leak contexts in inner classes.
- Use static inner classes over non-static.
- Use LRU cache for the bitmap to avoid redundant decoding of bitmap, it reduces GC calling again and again.
- Use StrictMode to find things you did by mistake like an accidental disk or network access or database query on the application's main thread in Android Development.
- Use Profile GPU Rendering: It gives a quick visual representation of how much time it takes to render the frames of a UI window relative to the 16ms benchmark. You can enable it from
Settings -> Developer Options -> Monitoring Section -> Select Profile GPU Rendering.
- And finally, do not allocate a large number of unnecessary objects.
Master Kotlin Coroutines from here: Mastering Kotlin Coroutines
That's it for now.
You can connect with me on: