akveo / react-native-ui-kitten

:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/react-native-ui-kitten/
MIT License
10.34k stars 956 forks source link

Performance issue with mutli-select/autocomplete list #1215

Closed eyalyoli closed 1 year ago

eyalyoli commented 4 years ago

💬 Question

Hello there 😄 I have a multi-select list with 180 options and it performs really slow. Every time I interact with the list I get: "VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. {"contentLength": 1760, "dt": 3394, "prevDt": 1798}"

Initially, I tried using autocomplete list thought it would be better, but it had similar performance issues. I am running dev env with bootstrapped metro bundler (according to this page) and hot-reload (expo project).

This is what my code looks like:

const [langs, setLangs] = useState(); //textual array of  langs
const [langIndexes, setLangIndexesRaw] = useState(); //indexes array of langs

const setLangIndexes = (i) => {
    setLangIndexesRaw(i);
    const langs = i.map((i) => constants.PLAIN_LANGUAGES[i.row]);
    setLangs(langs);
  };

<Select
        label="Language"
        placeholder="Language"
        multiSelect={true}
        value={langs?.join(", ")}
        selectedIndex={langIndexes}
        onSelect={(index) => setLangIndexes(index)}
      >
        {all_langs_items} 
      </Select>

all_langs_items is initialized externally - not in the scope of the component:

const all_langs_items = all_lang_names.map((item) => <SelectItem key={item} title={item} />);

I appreciate the help, I tried different tricks with the state but didn't help much.

UI Kitten and Eva version

Package Version
@eva-design/eva 2.0.0
@ui-kitten/components 5.0.0
eyalyoli commented 4 years ago

Ok, I guess that list is not meant for 200 items (maybe the native implementation is better), I've returned to using autocomplete and managed to optimize it by forcing the user to enter the first letter and then showing only up to 10 results that start with the entered letter.

jorgegvallejo commented 3 years ago

Just ran into this issue with multi-select as well. My list has 12 items in it and it's also really slow. Loading it takes a good 2-3 seconds, and interacting with takes ~1.5s. Single select is only slow when loading in my case.

Edit: Using FlatList inside the select seems to improve loading times slightly

eyalyoli commented 3 years ago

If you are using a dynamic list as a source, you should wrap the list with memo

jorgegvallejo commented 3 years ago

If you are using a dynamic list as a source, you should wrap the list with memo

Thank you and yeah tried that and it has no effect

PupoSDC commented 3 years ago

My case is even more ridiculous. My list has 3 items and it still takes a solid second for it to open / close:

const selectOptions: Array<[QuestionFilter, string]> = [
  ["ALL", "All"],
  ["WRONG_ONLY", "Wrong only"],
  ["NEVER_SEEN_AND_WRONG", "Never seen and wrong"],
]

// ...

  const [questionFilterIndex, setQuestionFilterIndex] = useState(
    new IndexPath(0)
  );

//...

          <Select
            selectedIndex={questionFilterIndex}
            multiSelect={false}
            value={selectOptions[questionFilterIndex.row][1]}
            onSelect={(index) => {
              if (!Array.isArray(index)) setQuestionFilterIndex(index);
            }}
          >
            {selectOptions.map(([key, title]) => (
              <SelectItem title={title} key={key} />
            ))}
          </Select>

full code available here.

AntonBorovoi commented 3 years ago

Hi @PupoSDC Could you please add more details on how to reproduce the issue? Maybe some specific steps? I just tried your repo locally on simulators and it works fine for me

PupoSDC commented 3 years ago

HI @AntonBorovoi

I haven't touched that project for quite some time, so I had to spin it up again. Here are my (Reviewed) findings:

I have a lot of version bumping to do though, so it could be that this issue has been addressed in the meanwhile...

brkastner commented 3 years ago
  • Im unable to get it to compile on android right now, but Im pretty sure my complain was based on my experience using the app on android (at the time i didnt have an IOS device).

I can confirm that debug builds on a physical Android device experience the same issue on v5.1.0.

Works fine on iOS but even with a static SelectItem list, Android still takes a few seconds to open/close the menu even though my list contains only 5 items.

anferrat commented 1 year ago

Run into the same issue on Android, ended up replacing SelectItem map with the FlatList or List. Surprisingly it worked, but it also killed all multiselect and select functionality: list with options was appearing but I couldn't select anything, and checkboxes on the left disappeared. Then I re-wrote onSelect added my own state to manage selected items, added selected option formatting to SelectItem along with CheckBox accessory and it finally... it worked. Faster than the original Select, plus FlatList allows to tweak rendering a little. I guess if you need SelectGroup, it can become a little too much, but certainly doable.

bataevvlad commented 1 year ago

We would be happy to try to reproduce this problem and help you find a solution, but with the current provided variations on our side everything works without any problems.

If you can give us more details on the code as you use it, we would be happy to help you.

At the moment we will close the ticket until you report back, there is a chance that this problem has been resolved in the new version of the package due to updates to the methods of displaying the SelectItems.