[Autocomplete] Slow despite virtualisation
See original GitHub issue- The issue is present in the latest release.
- I have searched the issues of this repository and believe that this is not a duplicate.
Current Behavior 😯
Autocomplete
maps over groupedOptions
and creates React elements where the number of items can be tens of thousands (e.g. list of stocks): https://github.com/mui-org/material-ui/blob/f23207bf2312eba2686522f904d72aea7d3c0a88/packages/material-ui/src/Autocomplete/Autocomplete.js#L670
Turns out this is quite slow and can take >1s to simply open the listbox when clicking on the Autocomplete
input:
Check line 456 which is where the .map
call takes place.
Expected Behavior 🤔
I believe that Autocomplete
should accept a renderListbox
render prop that would allow the consumer to be in control of how it’s rendered. I managed to hack something together in node_modules
, and you can see the interaction is a lot faster:
Steps to Reproduce 🕹
Steps:
- Navigate to https://codesandbox.io/s/virtualize-material-demo-forked-6hdqd?file=/demo.tsx which is a fork of the Virtualized example but with the number of options increased from 10,000 to 26,000
- Click on the input
- Observe a significant delay before the listbox opens
Context 🔦
I’m trying to render a rather large list of options, and was surprised that virtualisation didn’t help much. That being said, the UX is pretty terrible with that many options anyway, and maybe I should use limit
option of createFilterOptions
instead.
Your Environment 🌎
`npx @material-ui/envinfo`
System:
OS: macOS 10.15.7
Binaries:
Node: 12.18.2 - /usr/local/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.5 - /usr/local/bin/npm
Browsers:
Chrome: 89.0.4389.90
npmPackages:
@emotion/react: ^11.1.5 => 11.1.5
@emotion/styled: ^11.1.5 => 11.1.5
@material-ui/core: 5.0.0-alpha.27 => 5.0.0-alpha.27
@material-ui/lab: 5.0.0-alpha.27 => 5.0.0-alpha.27
@material-ui/styled-engine: 5.0.0-alpha.25
@material-ui/styles: 5.0.0-alpha.27
@material-ui/system: 5.0.0-alpha.27
@material-ui/types: 5.1.7
@material-ui/unstyled: 5.0.0-alpha.27
@material-ui/utils: 5.0.0-alpha.27
@types/react: ^17.0.0 => 17.0.3
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
typescript: ^4.1.3 => 4.2.3
Issue Analytics
- State:
- Created 3 years ago
- Reactions:5
- Comments:12 (12 by maintainers)
Top GitHub Comments
@NMinhNguyen Thanks for opening the issue. I have tried to render 100,000 rows. It’s REALLY slow. It takes about 10s to open in dev mode. This is pretty interesting as it’s slightly counterintuitive. I always thought that creating a LOT of elements with React was cheap. Anyway, here is how to get the demo render x30 faster:
I have said F**K to TypeScript with the any. If somebody wants to look into how to get better types coverage, that would be great.
Can we avoid doing
toArray
alltogether and just recommend using<Autocomplete>{[ <A />, <B />]}</Autocomplete>
? We expect a flat list anyway and re-keying shouldn’t be necessary. Or maybe still usetoArray
but add a warning at >100 items that you should just create the array instead?Seems like
toArray
usesmapChildren
internally which uses a bunch of needless.call
and.apply
which are probably responsible for the slowness.