henninghall / react-native-date-picker

React Native Date Picker is datetime picker for Android and iOS. It includes date, time and datetime picker modes. The datepicker is customizable and is supporting different languages. It's written with native code to achieve the best possible look, feel and performance.
MIT License
2.21k stars 338 forks source link

Loading is slow on Android #12

Closed kimhafr closed 5 years ago

kimhafr commented 6 years ago

Hi Henning,

Thanks for this great library, just what we've been looking for!

We've tried implementing this in our app, but it seems to load slow on Android. After some debugging we've located the issue in PickerView.java

Both in setMode and setLocale you call the applyOnAllWheels method, and we've measured this to take between 200 and 400 milliseconds each time on the emulator. They are of course faster on a device, but its still too slow in a production build. If commenting these out, the view loads fast (except it won't work of course). I'm not sure how to solve that, but maybe you have an idea?

kimhafr commented 6 years ago

So digging a bit more and found this in init in DayWheel.java:

        int min = 0;
        int max = 10000; // bug
        Calendar cal = pickerView.getInitialDate();
        cal.add(Calendar.DAY_OF_MONTH, -max/2);

        for(int i=0; i<=(max-min); i++){
            values.add(format.format(cal.getTime()));

            // Print "today" if date is today
            if(i == max/2){
                String todayString = Utils.printToday(pickerView.locale);
                String todayStringCapitalized = todayString .substring(0, 1).toUpperCase() + todayString.substring(1);
                displayValues.add(todayStringCapitalized);
            }
            else displayValues.add(displayFormat.format(cal.getTime()).substring(3));
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }

That loop running 10'000 times (multiple times) is the problem. You are probably aware due to the //bug comment 😃

henninghall commented 6 years ago

Hi Kim, nice to hear!

Thanks for reporting this! 👍 I definitely agree that the performance could be optimized on Android. I will have a look at it at some point but I can't guarantee a quick fix. If you find anything else that might be of interest to track down performance bottlenecks, please let me know!

EDIT: Commented before I saw your last comment! Great find, yes that's probably one reason that could improve it a lot. I also think we should avoid the duplicate rendering.

donatoaz commented 5 years ago

Just a note to people who get here because they are still experiencing jankiness and slowness even after v2.0.3, check if (and what) you are passing in the maximumDate and minimumDate props.

I was passing a date 100 years ago and it was taking several seconds to load.

Anyways, thanks so much for the work guys! 🎉

tunaSalad2406 commented 5 years ago

still got slowness on android guys

henninghall commented 5 years ago

@tunaSalad2406 could you send your picker code with props included?

tunaSalad2406 commented 5 years ago

it was super slow on device since i set the minimumDate in latest version 2.3.0. i have to degrade to 2.2.1 and it works fine for me now sir thankiu

henninghall commented 5 years ago

Okay thanks, i will have a look at it and see if anything went wrong in 2.3.0. What dates are you setting minimumDate and maximumDate to?

tunaSalad2406 commented 5 years ago

My code: <DatePicker date={this.customerStore.customerDoB} onDateChange={this.customerStore.setCustomerDoB} textColor={'#1E90FF'} mode="date" minimumDate={new Date(1970, 1, 1)} />

henninghall commented 5 years ago

@tunaSalad2406 Thanks! I am trying to find the slowness you are having. Is it the initial load time or changing the date that you find slow?

henninghall commented 5 years ago

@tunaSalad2406 I have made some improvements that I think will resolve your issue. I would really appreciate if you would like to try it out and let me know if it solved your issue 🙂

Do the following to try it out:

  1. Change the line in your package.json to: "react-native-date-picker": "henninghall/react-native-date-picker#performance"

  2. npm install or yarn

  3. rm -rf node_modules/react-native-date-picker/example && rm -rf node_modules/react-native-date-picker/example-cocoapods

  4. react-native run-android

tunaSalad2406 commented 5 years ago

@tunaSalad2406 I have made some improvements that I think will resolve your issue. I would really appreciate if you would like to try it out and let me know if it solved your issue 🙂

Do the following to try it out:

  1. Change the line in your package.json to: "react-native-date-picker": "henninghall/react-native-date-picker#performance"
  2. npm install or yarn
  3. rm -rf node_modules/react-native-date-picker/example && rm -rf node_modules/react-native-date-picker/example-cocoapods
  4. react-native run-android

sir it has nothing to complain now. many thanks you.

henninghall commented 5 years ago

Great, I will let you know when the fix is released. Thanks for the help!

inoutw commented 5 years ago

Hi Henninghall, when I

  1. Change the line in your package.json to: "react-native-date-picker": "henninghall/react-native-date-picker#performance" and yarn , it will auto install the lastest version 2.3.0. what should I do?
henninghall commented 5 years ago

@inoutw You probably need to remove the lock file or the part of the file concerning react-native-date-picker

inoutw commented 5 years ago

Yes, Henning, I have removed the lock file and delete all the file in node-modules then yarn for my project, still get the same. I checked the code in branch performance, the version is 2.3.0, which seems not include the code for this performance improvement

henninghall commented 5 years ago

Since I haven't made a new release of this yet the version will look the same. But yes, it does include 2 more commits as you can see https://github.com/henninghall/react-native-date-picker/commits/performance

henninghall commented 5 years ago

Released this fix in v2.4.0

slauzinho commented 5 years ago

This is still happening on Android "react-native-date-picker": "^2.6.1" when I have a maximumDate set. Doesn't happen on iOS or when I remove that prop.