Selectbox too slow when too many options

Hello!
I have a selectbox with 100k+ options and it takes a bit too long to interact with it.
Is there any way I can reduce the delay? Maybe somehow reduce the number of visible options from the dropdown, or none at all?
Thamks :pray:t2:

You could try caching the function that loads options into the selectbox. Check the Streamlit documentation about optimizing performance.

1 Like

Hello Elwyn,

I recently ran into the same problem and I was able to find a workaround. The issue seem to be related to the fact that it is difficult for the browser to render all the results under the dropdown, especially when you type only a few characters and there are too many results. So the trick is to only return the top k results.

To do that, I forked streamlit from the repository and changed the following file/line: streamlit/Selectbox.tsx at 1.13.0 ยท streamlit/streamlit ยท GitHub

More precisely I replaced:

  private filterOptions = (
    options: readonly Option[],
    filterValue: string
  ): readonly Option[] =>
    fuzzyFilterSelectOptions(options as SelectOption[], filterValue)

with (added a slice to return only the first 30 results after the search):

  private filterOptions = (
    options: readonly Option[],
    filterValue: string
  ): readonly Option[] =>
    fuzzyFilterSelectOptions(options as SelectOption[], filterValue).slice(
      0,
      30
    )

Now it is fast. You can adapt the number of results (change 30 to any value) depending on the usage.

You can do the same for the multiselect by changing the file/line: streamlit/Multiselect.tsx at 1.13.0 ยท streamlit/streamlit ยท GitHub

More precisely, by replacing:

    return fuzzyFilterSelectOptions(
      unselectedOptions as MultiselectOption[],
      filterValue
    )

with:

    return fuzzyFilterSelectOptions(
      unselectedOptions as MultiselectOption[],
      filterValue
    ).slice(0, 30)

Once done, you need to rebuild/install the package by running, from the streamlit root directory:

make -f Makefile all 

Or if you want to obtain the archive package in โ€œstreamlit/lib/distโ€ to install later with pip, you can run

make -f Makefile package

Youโ€™ll need to have npm/node14 installed. (it is prebuilt on my fork here if you want to save some time: streamlit/lib/dist at develop ยท wissam-sib/streamlit ยท GitHub )

Important note: The best solution would be to avoid modifying the regular components behaviour but rather building custom components that are copies of the base components where you do the modifications (Iโ€™ll try to work on that and repost a solution here later).

Good luck,
Wissam

2 Likes

Hi @wissamsiblini, thanks for your response above. I have an use case where Iโ€™m building an app to show informations about a company. The problem is that Iโ€™m working with 2 million companies and Iโ€™m building a page so that it shows information about only one company each time. So my first idea is to use a selectbox with the list of company names. But since this list is so long, the widget becomes very slow.

I will try to use the solution you showed above but have you had the time to build a component with this little tweak?

Best regards Mateus

1 Like

Hi @mateusccoelho,

  1. how about making a button list of 26 alphabets, so that you can click onโ€ฆ say โ€˜Aโ€™ and get the selectbox to display all companies that start with the letter โ€˜Aโ€™. That way you can lessen the load on the selectbox.

  2. You could try to use the fabulous component by @blackary (link: GitHub - blackary/streamlit-keyup: Streamlit text input that returns value on keyup) to see if it works for you.

Cheers

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.