joshuapinter / react-native-unified-contacts

Your best friend when working with the latest and greatest Contacts Framework in iOS 9+ in React Native.
MIT License
158 stars 56 forks source link

[Android 6.0 / 7.0] Crashes and slowdowns when fetching contacts > 500 #78

Open nningego opened 6 years ago

nningego commented 6 years ago

Hello,

We are testing on Galaxy S5 (Android 6.0.1). We noticed huge performance issues when reading contacts as the contact list grows.

At ~500, 'getContacts' fails with error "Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference -- getPhoneNumbersFromContact (RNUnifiedContactsModule.java:430) -- getContactDetailsFromContactId (RNUnifiedContactsModule.java:272)" [Seems to point to a null here: https://github.com/joshuapinter/react-native-unified-contacts/blob/master/android/src/main/java/com/joshuapinter/RNUnifiedContacts/RNUnifiedContactsModule.java#L430]

On Android 7.0, we see performance issues as well. Takes about 1 minute 40 seconds to read about 700 contacts from phone and this causes the app to lock for that time.

Has anyone managed to get around this issue?

joshuapinter commented 6 years ago

We haven't encountered any of these issues yet. If you are able to do more testing to narrow down the culprit, that would be great. I know with iOS the thumbnail data was causing some performance issues, especially because it has to send that data over the React Native bridge.

paintedbicycle commented 6 years ago

I've heard a bit about this in the issues of other contacts modules. Basically Android runs out of memory. One solution is to return a smaller range of contacts (like the result of a string search or the first batch of paged contacts like (A-E, then the next batch)

nningego commented 6 years ago

A quick look through the android profiler points to getContentResolver().query() taking most amount of time. There a few ways of improving performance -> https://stackoverflow.com/a/12121620. But I don't see them improving it drastically.

Fetching data as needed would help performance a lot, since getContacts is spending a lot of time fetching every detail when it might not be needed. Perhaps allowing user to query for a subset of contact details such just the names, or names+address, etc would lead to faster response.

Also the app is stuck while contacts are being read from the device, affects user experience much more. Using AsyncTask [https://developer.android.com/reference/android/os/AsyncTask] will help with this.

screen shot 2018-07-01 at 16 13 58
joaodematejr commented 5 years ago

same problem when I will upload more than ~50 contacts

adcuz commented 5 years ago

I am finding this is locking up the device for 5-10 seconds for ~80 contacts being loaded.

Graren commented 5 years ago

I can confirm, calling getContacts on 700 contacts it took around 2:30 minutes with a frozen JS thread on a mid range phone.

Just for a bit of context in case it helps, it was called inside a saga to obtain and cache the user's contacts for in-app use. However the moment the saga called a promise wrapping getContacts every interaction stopped working, sagas froze, navigation etc...

After the promise resolved it was back to normal. I did not turn on the profiler, but certain things (like scrolls) did work so I assume the UI thread was up and running, but no javascript was being processed