We live in times where mobile apps have to not only do their job but also do it smooth and delightful. In times where almost every Android device has huge computing power and operating system is really mature (and I’m not saying only about Lollipop or Marshmallow). Less and less things limit us to to deliver really beautiful apps.
But it also means that there are no excuses for us — the developers. We cannot say anymore: “this is because your crappy Android device… Do you want smoothness? Let’s check it on iPhone.”. Now it’s our fault that app works and looks good only on this year’s high-end device. We cannot blame platform developers anymore because they already did awesome job with optimizations in Android.
Moreover, they started sharing their knowledge about performance, optimizations and how things work under the hood. If you haven’t seen it yet just take a look at this videos collection — Android Performance Patterns. Do we need more proves that now everything is really in our hands?
Where to start with performance improvements?
In most cases, especially in bigger apps, probably the most affected places are app launch process and navigation between screens. In general let’s say that if your app launches longer than 1 or 2 seconds and you don’t have a good explanation why, there is something wrong. Similarly with screens navigation — if you have to wait for a screen a noticeable moment after you tap on button something is definitely not ok.
Here are a couple of reasons which can cause those kind of issues:
- App initializes a lot of (or not so much, but heavy) objects in launch process.
- App is doing some heavy operations in Activity lifecycle starting methods — onCreate(), onStart() or onResume() (so it’s happening after user clicks on button but before screen is visible).
- Layout is too rich and/or too complicated to measure and draw it for the first time.
It’s obviously not easy to measure app launch time or each of Activity lifecycle methods every time when we compile the app. And that’s why I’d like to introduce you very first version of metrics tool for Android development:
Performance metrics library for Android development.
The problem with performance is that it often decreases slowly so in day-by-day development it’s hard to notice that our app (or Activity or any other view) launches 50ms longer. And another 150ms longer, and another 100ms…
With AndroidDevMetrics you will be able to see how performant are the most common operations like object initialization (in Dagger 2 graph), or Activity lifecycle methods (onCreate(), onStart(), onResume()).
It won’t show you exact reason of performance issues or bottlenecks (yet!) but it can point out where you should start looking first.
First iteration of this tool (v0.3) is able to measure:
- Objects (and dependencies) initialization in Dagger 2 graph
- App and screens launch process (measuring lifecycle methods execution)
- Frame drops on each screen
Script below shows how to enable all available metrics.
In your build.gradle:
In your Application class:
How does it work?
Detailed description how it works under the hood can be found on projects wiki pages:
I found performance issue, what should I do next?
There is no silver bullet for performance issues but here are a couple steps which can help you with potential bugs hunting.
If measured time of object initialization or method execution looks suspicious you should definitely give a try toTraceView. This tool logs method execution over time and shows execution data, per-thread timelines, and call stacks. Practical example of TraceView usage can be found in this blog post: Measuring Dagger 2 graph creation performance.
If it seems that layout or view can be a reason of performance issue you should start with those links from official Android documentation:
Finally, if you want to understand where most of performance issues come from, here is a collection of videos focused entirely on helping developers write faster, more performant Android Applications — Android Performance Patterns.
You can check GithubClient — example Android app which shows how to use Dagger 2. Most recent version uses AndroidDevMetrics for measuring performance.
Source code of AndroidDevMetrics is available on Github project site.