Why my app freezes for some time on the first launch?
For an example animations of screen transitions or collapsing toolbar freezes on first showing time. If I kill the app completely and open it again there is no issues with performance. It happens even with release build type
If releasing a memory by killing your app helps to 'resolve' this issue, it a sign of memory leak. Do you use leak canary in your project (https://github.com/square/leakcanary)? If not, please add and test your app to figure out if there is a memory leak.
Freeze is also might mean some resource consuming task in the MainThread. Do you use a StrictMode? If not, please add it and see reports\crash -- it will help you to figure out if you or 3rd party library execute some time consuming operations in the MainThread. However even if your app passes StrictMode, you still can have other types of heavy operations, e.g. solving a complex differential equation, in the MainThread
Finally, Android Studio provides a good tools for app performance analysis. Please check them to find out less obvious performance issues.
There are many ways to freeze your app, the most common is to already have a heavy task run in long time at main thread, such as: load a large photo resource, call a restful api..etc
you should check more information at https://developer.android.com/topic/performance/vitals/tracking_jank
Related
Performance issue
We experience performance issues with our ReactNative app unblnd.com/app.
The app starts being slow on most Android phones after a few minutes using the app (after install).
What has been done?
A) Api Request
Some api requests are a bit slow, but querying has been improved. The queries don't influence the app performance on iPhone. Concluded can be that the api requests aren't making the app laggy.
We will temporarily boost our server within AWS to completely make sure this isn't causing the issue.
B) Navigation
We found some sources stating react-navigation v5 would be slow. Therefore we looked to the navigation stack, but we get a similar slow performance with react navigation v4 and v5:
#react-navigation/native: ^5.9.4
#react-navigation/stack: ^5.14.5
---
react-navigation: ^4.4.4
react-navigation-stack": ^2.10.4
C) Caching / Memory
The caching size increases from 0MB to 12MB when using the app. The app could already be slow from 3MB caching size. It seems doubtful this can be blocking the flow as other apps can take up more than 1GB cached data size.
D) React Context
We have an extensive chat system. All the screens related to the chat are wrapped into a react context. We have been cleaning the stored data into the context, but the app can be slow for users having not that much chat data cached in the context too. Therefore, too many repetitive renders could cause an issue?
<ChatContext.Provider value={{...}}>
<Stack.Navigator>
<Stack.Screen ...>
x 20
</Stack.Navigator>
</ChatContext.Provider>
There are 20 screens in the React Context. Is there any good practice regarding contexts?
To do:
We will make an app version without context;
How can we monitors these (potential) renders?
E) Monitoring
We started using Sentry Monitoring. There are no specific issues raised. Within Performance only http requests are shown. Sometimes it just states navigation and sometimes with missing integration.
Using FlatList we get
VirtualizedLists should never be nested inside plain ScrollViews with
the same orientation because it can break windowing and other
functionality - use another VirtualizedList-backed container instead.
We could try to solve this, but this cannot cause blocked navigation for the whole app?
F) Memory Leaks
The most obvious one looking to the symptoms. But it is really difficult to find out what could cause such memory leak.
Within Sentry we just found one clue about a memory leak. We just disabled this component, but Android phones are still slow.
Guidance
We have been trying and fixing lots of different parts. Anyone has tips, ideas, recommendation to find our what is causing the slowness on Android phones?
General Info
npmPackages:
react: 17.0.1
react-native: 0.64.2
You should profile your app to see what's slowing things down. You mentioned that it only starts being slow after a few minutes, I guess I would look into seeing if this happens after some reproducible event. Does it happen only if you open this one screen, or every time etc. I agree with you that this smells of a memory leak.
If you already use Sentry you also can use the Sentry.Profiler to profile a component to see how long each lifecycle method takes.
My customer raise a problem about our app which is the app is getting slower when using for long time, but our side cannot simulate the problem as we are not in their real working environment, we are not able to solve the problem before knowing the bug. anyone can help?
If it´s a issue that raises "by the passing of time", you should look for any task you might be running and repeating itself.
You should check the different types of functionalities you use.
For example, if your app it´s using a local database:
Look for unclosed cursors.
I/O work
If your are using animations:
Look for skipped frames
Complex view hierarchies
If using background tasks or threading:
I/O work
Unfinished threads
Increasing thread number
If using networking and Webservices:
Problems with your server database
Connection issues
Proxys
...
You could also use something like Firebase + Crashlytics to see if theres any warning raises but gets silently disposed.
Giving some more info about your app and what it does could be useful for elaborating more accurate solution.
A common source of slowing down apps is memory leaks.
on iOS what you can do is to activate Memory management flags on your target and keep a watch on the logs, you can also use Xcode Memory Graph and instruments leak tools to detect leaks.
on Android you can use tools like LeakCanary to be notified when leaks happens.
Once you have a leak detected you can inspect your code to identify the source and better manage memory.
#axierjhtjz mention lots of good starting points.
Does it occur on both iOS and Android, specific devices, vendors?
If it is mainly on a single platform (Android/iOS), on different devices and the main complaint is slowness over time, I would suspect the following:
Memory leak (maybe UI, fragments)
Data persistent data incremental over time or/and more IO operation over time.
If you unable to debug the problem on the customer site, I would suggest to add a remote real time monitoring capabilities over relevant parameters and logs.
A good tool we used in the past was TestFairy. maybe they have a free trial
My app is consuming a lot of memory
I have used the following app to measure my app memory consumption
https://play.google.com/store/apps/details?id=mem.usage&hl=en
can any one tell me how can I optimize the memory used by my app?
1) you can use LeakCanry for optimize memory. leakCanry will give you report for each individual leaks or when multiple instance of an activity will be on stack.
here is more info and integration guide https://github.com/square/leakcanary
2) you can check android studio memory monitor for your app's memory use. from that graph you can check when GC is being called and which activity or function is taking more memory so you can optimize through it.
more info regarding this http://developer.android.com/tools/performance/memory-monitor/index.html
3) i have gone through udacity tutorial and videos. you can see how to improving rendering for your layouts
Need to reduce unnecessary views.
dont apply unnecessary background.
more stuff https://www.udacity.com/course/android-performance--ud825
4) one more important thing use ApplicationContext where you can use it because Activity context keeps in stack and wont be eligible for GC until that context related task is being finished.
https://developer.android.com/tools/performance/comparison.html
Start with running Memory Profiler Tool to see what is the causes that leak/consume much memory in your app.
Is there something in Eclipse or possibly a 3rd party tool that lets me see how my app is using up memory while it is running? When my app runs, there appears to be something that over time starts eating up memory. It would be nice to see what class is responsible for it so that I can zoom in on the area that is causing the problem. It would be nice to see how memory is being used dynamically over time and what know what classes/methods are "leaking".
Traceview is there for the rescue. See the official documentation http://developer.android.com/tools/debugging/debugging-tracing.html .
You can check the memory leaks through it too. DDMS provides a UI for profiling also.
I'm trying to follow Android best practices, so in debug mode I turn all the following on:
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all thread violations
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build()); //detect and log all virtual machine violations
Android now yells at me when I try to use any sort of file access or SQL in the main (UI) thread. But I see so many recommendations to use file access and/or SQL in the main thread. For example, the main activity should load default preference values inside onCreate() in case they haven't been set yet:
PreferenceManager.setDefaultValues(context, resId, readAgain);
Oops---that results in a file access on the first application execution, because onCreate() is called on the UI thread. The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.
Think also of services such as the DownloadManager. (Actually, it's so buggy that it's useless in real life, but let's pretend it works for a second.) If you queue up a download, you get an event (on the main thread) telling you a download has finished. To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.
So what's the story---is it fine to access cursors in the main thread? Or is it a bad thing, and half the Android development team and Android book authors forgot about that?
The only way around it I can see is to start a separate thread---which introduces a race condition with other UI code that might read the preferences and expect the default values to already be set.
Then use an AsyncTask, putting the setDefaultValues() call in doInBackground() and the "other UI code that might read the preferences" in onPostExecute().
To actually get information about that download (it only gives you a download ID), you have to query the DownloadManager---which involves a cursor, giving you an error if you have a strict policy turned on.
So query the DownloadManager in a background thread.
So what's the story---is it fine to access cursors in the main thread?
That depends on your definition of "fine".
On Android 1.x and most 2.x devices, the filesystem used is YAFFS2, which basically serializes all disk access across all processes. The net effect is that while your code may appear sufficiently performant in isolation, it appears sluggish at times in production because of other things going on in the background (e.g., downloading new email).
While this is a bit less of an issue in Android 3.x and above (they switched to ext4), there's no question that flash I/O is still relatively slow -- it will just be a bit more predictably slow.
StrictMode is designed to point out where sluggishness may occur. It is up to you to determine which are benign and which are not. In an ideal world, you'd clean up them all; in an ideal world, I'd have hair.
Or is it a bad thing, and half the Android development team and Android book authors forgot about that?
It's always been a "bad thing".
I cannot speak for "half the Android development team". I presume that, early on, they expected developers to apply their existing development expertise to detect sluggish behavior -- this is not significantly different than performance issues in any other platform. Over time, they have been offering more patterns to steer developers in a positive path (e.g., the Loader framework), in addition to system-level changes (e.g., YAFFS2->ext4) to make this less of a problem. In part, they are trying to address places where Android introduces distinct performance-related challenges, such as the single-threaded UI.
Similarly, I cannot speak for all Android book authors. I certainly didn't focus on performance issues in early editions of my books, as I was focusing on Android features and functions. Over time, I have added more advice in these areas. I have also contributed open source code related to these topics. In 2012, I'll be making massive revisions to my books, and creating more open source projects, to continue addressing these issues. I suspect, given your tone, that I (and probably others) are complete failures in your eyes in this regard, and you are certainly welcome to your opinion.