react-select: React-select is slow when you have more than 1000 items
Low performance on large sets of options
React-select slows down when you have a huge array of data. Mouse

FPS drops so low on mouseover, that i can barely use it. In my real case, where i have 1010 items, which i need to show(and i can’t load them as user types) - i cannot do anything at all.
You can find a simple example in codesandbox.
https://codesandbox.io/s/q8l6xnvz7w
[Violation] 'mouseover' handler took 346ms
[Violation] 'mouseover' handler took 184ms
[Violation] 'mouseover' handler took 197ms
[Violation] 'mouseover' handler took 172ms
[Violation] 'mouseover' handler took 161ms
[Violation] 'mouseover' handler took 150ms
[Violation] 'mouseover' handler took 167ms
[Violation] 'mouseover' handler took 172ms
[Violation] 'mouseover' handler took 156ms
[Violation] 'mouseover' handler took 166ms
React-select version: 2.1.0
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 102
- Comments: 87 (1 by maintainers)
Two things to look into that may help with your issues, we also had some issues regarding large lists.
filterOption={createFilter({ignoreAccents: false})}
Take a look at this reported bug https://github.com/JedWatson/react-select/issues/2850
There’s two examples using React-Window, which greatly improves the performance.
https://codesandbox.io/s/lxv7omv65l
If it’s the typing lag that you’re bumping on (I was) then it’s actually the
filterOption={createFilter({ignoreAccents: false})}suggestion by @M1K3Yio that’s the gem.Using this massively reduces the lag when you’re typing into the select. I’ve got a sandbox here that illustrates: https://codesandbox.io/s/zn70lqp31m?fontsize=14
And I’ve blogged it too
Based on the responses above, I came up with this:
Then, whenever I have to optimize a
<Select />I pass a couple of extra props, ie.:Given the required dependencies are installed, others using typescript should be able to create a file for the
optimizeSelectand use it as in the example above.Summarized and working for me:
and your css file:
Hope somebody can make use of this too. I’d still prefer a fix.
Is there any reason why virtualization isn’t built into react-select? I personally cannot think of a reason why it shouldn’t be.
Probably not the best approach. But it’s working for me. If anyone has suggestions for improvement, I would be grateful.
I have a quick work around fix: Pass your own MenuList component, iterate through the childs and remove this props below. It stops lagging then. But you need to add styles for hover via css then.
delete key.props.innerProps.onMouseMove; delete key.props.innerProps.onMouseOver;
hm, this component was praised as “the best solution” and it cannot handle a couple thousand entries?
after I click, it takes seconds to render the drop down and in the console I have
a bit disappointed, honestly.
neither
ignoreAccents={false}norfilterOption={createFilter({ignoreAccents: false})}seems to help we have 9k entries
my whole browser freezes and stutters, it’s absolutely unusable
Hi everyone! I spent a few days solving the dropdown list freezing issue. I tried using the above described methods of creating
MenuListusingreact-window. I also added a customOptioncomponent, removing propsonMouseMoveandonMouseOver. Seems this fixed my problem.Example with
react-windowcodesandbox.Update:
Example with
react-virtuosocodesandbox.MenuList
Option
ReactSelect
I was bashing my head against the wall with this performance issue. Then, after watching user behavior, I’ve noticed that users don’t scroll huge lists – they’re using exclusively search. So we’ve published a version that shows only a portion of options but searches through all of them:
CodeSandbox
Performance issues are gone and nobody noticed that some options are missing (since all options are searchable by typing). It’s not a perfect solution but I hope my experience is helpful for someone
i love how this thread is still going after all this time.
just ask GPTChat to write your implementation.
Or paste (a simplified version) of your implementation into GPTChat and ask it to correct. Tell it what’s wrong. Show it where it hurts. It will help you.
🤖🤖🤖
Example of @shunfan solution
This did the trick. Thanks man
I’d remove Jossnaz’s comment above ☝️ . It’s just not useful at all and this person clearly doesn’t understand how hard it is to build a component like this. Try using a native browser’s dropdown and tell me how far you get in functionality!
Just wanted to say that I found this issue while trying to debug some performance problems I was having and found all the discussion very enriching. I’m using react-virtualized as well and my selects start to lag around 500 elements.
I only wanted to ask two things: 1- Is there any loss in functionality if I remove the mouse handlers? 2- Would it be useful to have a wiki entry explaining this? (edit: I would volunteer for this if that’s the case) Like many others, my use case is to provide search in a large dataset, so, knowing this in advance (by referencing this issue in the docs) would be very helpful to plan ahead.
Thanks for the work!
The performance penalty for filter each option in a quite large set of data is insanely slow on force reconciliation a new
react-select, as https://github.com/JedWatson/react-select/issues/3128#issuecomment-431397942 suggested must be disabled, I even would recommend the author disable it by default.In my case, I am dealing with a set of 2000 items and I do not need to filter, so I disable the whole thing, the speed bost quite a lot, check the time just the filter method takes.
Furthermore, following the recommendation of https://github.com/JedWatson/react-select/issues/2850 I’m using
react-windowwith a customMenuListfor only large datasets. Here the implementation in Typescript.I hope that helps, this is still a workaround, but it works for me pretty well.
Removing the mouse events from Option and providing your own hover styling via CSS improves performance considerably, but it means the
isFocusedprop doesn’t get updated on hover, which results in multiple elements being highlighted when you hover (assuming you have a highlight style set forisFocusedEven a list with relatively few items is very slow with the mouse events enabled, I have a list with <100 items and running my mouse up and down the list is super laggy. I’m not sure what the solution could be here, removing styling for
isFocusedmakes the component impossible to use with the keyboard. Another option might be to make use of React.memo and possibly useCallback or other memoization tricks in order to prevent so many re-renders. In theory when focus changes only two options should need to be updated: the option that is going from not focused to focused, and the option that’s going from focused to not focused. I tried the super naive approach of just:But there are definitely more props than just those changing as subsequent focus changes after the first one don’t cause any elements to re-render.
Works perfectly! Btw styling can be done inside the MenuList component like this:
or like this: (tailwind itc)
Just wanted to build on the existing solutions – this was the one I ended up on. Initial implementation was built off of the solution provided by @badwarlock https://github.com/JedWatson/react-select/issues/3128#issuecomment-847149453
I wanted to have something more keyboard navigable, but it turns out I needed to make it into a controlled component in order to get that to happen.
CSS:
Every time I move my mouse over an option, this component runs
filterOption()as if something could possibly have changed other than focus.I am genuinely perplexed by this performance issue and the maintainers’ apparent apathy toward it. If performance tanks with 100+ items, it doesn’t belong anywhere near a production environment… Virtualizing the list of options is like using a jackhammer to mount a poster to a wall — a bit much, to say the least.
I guess we need to find an alternative. Pretty infuriating that I’m noticing this issue long after having implemented this component into our design system.
Follow-up: Writing my own
Optioncomponent that strips outonMouseOverandonMouseMoveprops seems to work without breaking keyboard functionality. Maybe I’m missing something, but this thing still behaves the same without those props on my Options, which only further confuses me as to why they’re on there in the first place 🤔 Thanks to @shunfan and @kotvasiliIt is insane that ignoreAccents’ default is set to true!
Setting this to false, in my case where I’m pairing react-select with react-virtualized, resulted in huge perforance boosts, with very little lag if any. Been looking for this solution for a long time. Thanks @endbay !
I have 50,000 items in my Select from react-select. I tried many things to improve performance: set ignoreAccents to false, disable onMouseMove and onMouseOver events and virtualization. But it’s still slow.
Taking up @lynxtaa 's idea, I found the react-select-async-paginate library which allows you to “paginate” the items, and to retrieve the ones you want with the search.
The library : https://www.npmjs.com/package/react-select-async-paginate Example: https://codesandbox.io/s/10r1k12vk7?file=/src/App.jsx:673-688
@aaronmw
The simple reality is that there is a lot of work to be done by what is essentially a handful of people who are doing so on their free time. Version 5 is still fairly recent and was a huge undertaking and it also forced the team to pause development to achieve parity between what was present in Flow translated into TypeScript. The last few weeks have been focused resolving issues found following the release.
Our next focus will likely be on addressing Menu behavior issues which I spent my weekend searching through open issues to identify and categorize. https://github.com/JedWatson/react-select/discussions/4864 We also would like to address the issues caused by Emotion with the hopes of creating an unstyled version that removes that dependency.
If you would like to contribute more, please feel free to open a discussion so we can talk about performance ideas in depth and in a holistic way that includes the full context of what’s being done and why. There are some performance PR’s that have been merged https://github.com/JedWatson/react-select/pull/4388 as well as others we’d like to revisit https://github.com/JedWatson/react-select/pull/4514, but our time is finite and would certainly welcome more collaboration.
You can use this library
https://github.com/jacobworrel/react-windowed-select
Implements both react-select and react-window. Also, you can use the same properties that are available with react-select (https://react-select.com/props)
@endbay It worked for me. Thanks!
I’m pretty sure this project is accepting PRs
@aaronmw Come on, it’s not that much work to write a 20(ish)-line custom MenuList component:
This is a wonderful project and we should respect the fact people are doing this for free, so they make our lives easier.
Thank you!
People coming from Material-UI, follow @LukasMueller187 solution. It’s the most comprehensive one.
For me filterOption didn’t work, so i added
ignoreAccents={false}on the<Select />component.Soo for example:
I’ve used the ignore accents when calling the ReactSelect, that worked for me, give it a try…!
<ReactSelect className="react-select" styles={customStyles} ignoreAccents={false} {...props} />@chadlavi-casebook I used react-virtuoso. That works pretty nicely for varying height options.
We’ve tried using the
react-windowsolution suggested above, but that solution requires that you know the rendered height of each option. When options in a select are from user-generated content and the menu may be virtually any width, we have to calculate that on the fly every time.Anyone know a virtualization lib that can be used that doesn’t require you to know the exact height as rendered in the browser of every item in the list?
Can anyone give an example to fix this for grouped MenuList? When I use this https://github.com/JedWatson/react-select/issues/3128#issuecomment-576809096 example it overlaps groups on top of each other.
THIS WORKED PERFECTLY FOR ME, comment link
looks like https://github.com/JedWatson/react-select/issues/3128#issuecomment-576809096 works
Solution for Typescript users:
@gydotitulaer Thanks for your response. I intended to focus on
asyncselect components such as<AsyncSelect/>,<AsyncCreatable/>which should be along withloadOptionsprop.However, the problem I mentioned previously came out because I made a mistake with importing wrong function
createFilterwhile I tried some sort of ways.After I imported correct
createFilterfunction fromreact-select, then it worked.TLDR;
The following code worked as expected.
Just as a reference for anyone else who might encounter this problem, the solution using filterOption works like magic: filterOption={createFilter({ ignoreAccents: false })}
@dtaub thanks, that suggestion looks great. Bonus that it’s already written in typescript as well.
This solution has improved the performance for common browsers like Chrome, Firefox and Safari significantly. For IE, there still seems to be some lagging for large dataset(9563 records). Have you had the same issue?
I think delegation might help. Instead of subscribing every option element to mouseMove and mouseOver events we can subscribe only the parent element.
I have almost the same issue, but I’m displaying more than 3.000 elements. What i did was the to use React
useMemoand customize theMenuListand theOptioncomponent. At start the display list takes 3.6s (3872 items) and later everything takes 2.5s. It’s not a huge improvement but it’s something. I think you could gain some ms using a normal for loop (well done) instead of amapfunction and displaydivinstead of the<components.Option />but that depends of the requirementsTwo more hints that may help someone (I hope), that helped me after struggling with even react-modal-solution being a bit laggy. Deadly lags appeared while hovering and “mouseovering” the dropdown elements, with even “poor” 250 options. So hints that may help:
There is no interest of autocomplete without filtering the options. It’s just a simple select otherwise.