web-ridge / react-native-paper-dates

Smooth and fast cross platform Material Design date and time picker for React Native Paper
https://www.reactnativepaperdates.com
MIT License
642 stars 166 forks source link

Performance issues #208

Closed hyoretsu closed 1 year ago

hyoretsu commented 1 year ago

On the single date picker, it takes 2 seconds to change months and 1 second to select a day.

RichardLindhout commented 1 year ago

Android? Do you have enabled Hermes? Can I see your code, you should provide stable props the the date picker.

jwallet commented 1 year ago

yes android, on jsc with the basic implementation. It should not be so slow even with hermes disabled. it also takes 1-2 seconds to mount and show the current month. It's really slower that react-native-community pickers

RichardLindhout commented 1 year ago

Ofcourse because they are native and this is all kind of calculations in the touchables of RNP. Please monitor performance. React Native is just slow RN I've done all kind of crazy stuff to prevent re-rendering but it is slow on older android devices. But changing the date is your app which is re-rendering stuff again

RichardLindhout commented 1 year ago

So please look up if you app does heavy stuff when re-rendering or changing the date. Can you provide the code you use to implement the date picker in your app?

hyoretsu commented 1 year ago

It shouldn't be React Native. It's only this library that has this problem out of the ones I tested. All I had was a screen with a basic component from this lib in it.

jwallet commented 1 year ago

I even tried to remove all props and it's still always slow to render. I click on a day it takes 1 sec, I click on next/prev month it takes 2secs, but swiping it renders in half to 1 sec.

btw, you don't export fr translation from your package.

import { startOfDay } from 'date-fns';
import i18next from 'i18next';
import React, { useEffect, useState } from 'react';
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { TextInput, TouchableRipple } from 'react-native-paper';
import { DatePickerModal } from 'react-native-paper-dates';

import { formatShortDate } from '../../helpers/DateHelpers';
import translate from '../../helpers/Translate';

type Props = {
  style?: StyleProp<ViewStyle>;
  label: string;
  onChange: (value?: Date) => void;
  date?: Date;
  readonly?: boolean;
};

const DateTimeFieldPicker = ({ style = {}, date, label, readonly = false, onChange }: Props) => {
  const [value, setValue] = useState<Date>();
  const [displayValue, setDisplayValue] = useState<string>();
  const [isPickerVisible, setIsPickerVisible] = useState(false);

  useEffect(() => {
    if (date) {
      const startDay = startOfDay(new Date(date));
      setValue(startDay);
      setDisplayValue(formatShortDate(startDay));
    }
  }, [date]);

  const reset = () => {
    setValue(undefined);
    setDisplayValue(undefined);
    setIsPickerVisible(false);
  };

  return (
    <>
      <TouchableRipple
        style={[styles.input, style]}
        onPress={() => setIsPickerVisible(true)}
        onLongPress={() => reset()}
        disabled={readonly}>
        <View pointerEvents='none'>
          <TextInput
            disabled={readonly}
            style={{ backgroundColor: 'white' }}
            editable={false}
            mode='outlined'
            value={displayValue}
            label={translate(label)}
            right={!readonly && <TextInput.Icon style={styles.caret} size={15} name='chevron-down' />}
          />
        </View>
      </TouchableRipple>
      <DatePickerModal
        locale={'fr'}
        mode='single'
        emptyLabel={''}
        visible={isPickerVisible}
        onDismiss={() => null}
        onConfirm={() => null}
        label={''}
        startYear={2022}
        endYear={2022}
        onChange={() => null}
      />
    </>
  );
};

export default DateTimeFieldPicker;

const styles = StyleSheet.create({
  caret: {
    alignContent: 'center',
    alignItems: 'center',
    alignSelf: 'center',
    bottom: 0,
    justifyContent: 'center',
    left: 0,
    position: 'absolute',
    right: 0,
    top: 0,
  },
  input: {
    width: '100%',
  },
});
jwallet commented 1 year ago

If I remove Swiper it opens right away

jwallet commented 1 year ago

maybe it's worth saying that I'm using expo

RichardLindhout commented 1 year ago

These are not stable props: onDismiss={() => null} onConfirm={() => null} label={''} startYear={2022} endYear={2022} onChange={() => null}

RichardLindhout commented 1 year ago

Please add reproducible snack so we could fix this, currently it takes too much work to reproduce issues like this

It's probably because you don't use stable props (so if something changes the whole date picker re-renders)