Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Select] getting slow when loading 2000 options #17001

Open
gopinath-sixt opened this issue Aug 14, 2019 · 16 comments
Open

[Select] getting slow when loading 2000 options #17001

gopinath-sixt opened this issue Aug 14, 2019 · 16 comments
Labels
component: select This is the name of the generic UI component, not the React module! performance

Comments

@gopinath-sixt
Copy link

gopinath-sixt commented Aug 14, 2019

Current Behavior 馃槸

  • When Select Component rendered with 2000 options, getting delay to show the drop-down and select the value

Expected Behavior 馃

Need to be fast on showing the drop-down and selecting the value

Steps to Reproduce 馃暪

https://codesandbox.io/s/material-demo-5ygxr

Your Environment 馃寧

Tech Version
Material-UI v4.3.2
React 16.9.1
Browser chrome
etc.
@mbrookes mbrookes added component: select This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement labels Aug 14, 2019
@mbrookes
Copy link
Member

That's to be expected. You need to use a virtualisation solution, perhaps following this example: https://material-ui.com/components/lists/#virtualized-list

@oliviertassinari oliviertassinari added new feature New feature or request and removed support: question Community support but can be turned into an improvement labels Aug 15, 2019
@devsumanmdn
Copy link
Contributor

devsumanmdn commented Aug 21, 2019

That's to be expected. You need to use a virtualisation solution, perhaps following this example: https://material-ui.com/components/lists/#virtualized-list

@mbrookes with a usual virtualisation solution we'll lose full keyboard interactivity. For example, we'll not be able to type an option's text to move the focus. Is it possible to tweak something and have full keyboard interactivity with a virtualisation solution?

@mbrookes mbrookes changed the title material-Select getting slow when loading 2000 options [Select] getting slow when loading 2000 options Aug 21, 2019
@mbrookes
Copy link
Member

You might have to use the native select in that case: https://material-ui.com/components/selects/#native-select

@gopinath-sixt
Copy link
Author

Hi @oliviertassinari

Thanks for adding as Enhancement, we are waiting for upcoming release.

@mbrookes : By using native-select, options will not come in material design but we are expecting the performance in material-ui-select.

@eps1lon
Copy link
Member

eps1lon commented Aug 26, 2019

That's to be expected. You need to use a virtualisation solution, perhaps following this example: https://material-ui.com/components/lists/#virtualized-list

@mbrookes with a usual virtualisation solution we'll lose full keyboard interactivity. For example, we'll not be able to type an option's text to move the focus. Is it possible to tweak something and have full keyboard interactivity with a virtualisation solution?

It's one of the reasons why I prefer <Select options={[options]} /> + renderprops APIs. While a declarative API looks nice for few options it just doesn't scale for multiple options or custom renderers with type-ahead support. It's also much friendlier to types which would probably negate the reduced DX from using renderprops.

This applies essentially to all collection widgets (trees, lists and grids). I'll take a look at the current keyboard a11y implementation and how you would add virtualization to Select.

@KenNguyen-0107
Copy link

KenNguyen-0107 commented Feb 17, 2020

That's to be expected. You need to use a virtualisation solution, perhaps following this example: https://material-ui.com/components/lists/#virtualized-list

@mbrookes with a usual virtualisation solution we'll lose full keyboard interactivity. For example, we'll not be able to type an option's text to move the focus. Is it possible to tweak something and have full keyboard interactivity with a virtualisation solution?

It's one of the reasons why I prefer <Select options={[options]} /> + renderprops APIs. While a declarative API looks nice for few options it just doesn't scale for multiple options or custom renderers with type-ahead support. It's also much friendlier to types which would probably negate the reduced DX from using renderprops.

This applies essentially to all collection widgets (trees, lists and grids). I'll take a look at the current keyboard a11y implementation and how you would add virtualization to Select.

Hi @eps1lon,

did you have the time to checkout the implementation of virtualization to Select (either using React-Window or React-Virtualized).

My problem is pretty similar to this post here:
https://stackoverflow.com/questions/57799541/unable-to-select-item-when-using-textfield-or-select-with-react-window/60258515#60258515

@eps1lon
Copy link
Member

eps1lon commented Feb 18, 2020

did you have the time to checkout the implementation of virtualization to Select (either using React-Window or React-Virtualized).

Sorry, I didn't have time for it. Doesn't look like I will have bandwidth for this during OSS time in the near future.

@rvighnes
Copy link

https://material-ui.com/components/autocomplete/#virtualization

@mogadanez
Copy link

virtualization is good, but anyway concerning with overhead in performance
I have list of ~800 items

{list.map(s=>{
                      return <Fragment key={s.mediaID}>
                             <div className={classes.someClass}>{s.title}</div>
                        </Fragment>
                  }) }
{list.map(s=>{
                      return <Fragment key={s.mediaID}>
                             <Typography className={classes.someClass}>{s.title}</div>
                        </Typography>
                  }) }

the difference in execution time is 6-7 times.
if use ListItem instead of Typography, difference will be up to x20 times

@UnderTheMoonspell
Copy link

Will this ever be fixed? Ive researched around and the only solutions seem to be using virtualization with Autocomplete, which is not a Select (and Ive tried to make the Autocomplete work as a select by disabling typing, but could not make it work), so its really not a solution.

@oliviertassinari
Copy link
Member

@UnderTheMoonspell we might rebuild the select to solve this and a dozen other issues we have with the component.

@ItayTur

This comment has been minimized.

@m0onspell

This comment has been minimized.

@m0onspell
Copy link

So basically there's no way to integrate any virtualization solution with non-native Select component? I am not asking about List or Autocomplete.
Select requires you to pass MenuItem as direct descendants, so as the result you can't wrap them in say FixedSizeList from react-window.
Is there some way around it?

@maryannabt
Copy link

maryannabt commented Mar 31, 2023

@oliviertassinari Hello! Are there any updates on this issue? Regarding of virtualization in Select component specifically.

@gkiely
Copy link

gkiely commented Dec 3, 2023

For anyone looking into this further, the issue is the following:

MenuItem uses MenuItemRoot, MenuItemRoot is generated by styled which is calling createStyled. createStyled returns a jsx element that also does CSS processing for each react node, which it looks like is causing the slowdown.

  1. https://github.com/mui/material-ui/blob/master/packages/mui-material/src/MenuItem/MenuItem.js#L50
  2. https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/styled.js
  3. https://github.com/mui/material-ui/blob/master/packages/mui-system/src/createStyled.js#L132

You can get a high performance and functional list with no styles by replacing MenuItemRoot in MenuItem.js.

const MenuItemRoot = /*#__PURE__*/React.forwardRef(function MenuItemRoot({ focusVisibleClassName, ownerState, ...props }, ref) {
  if(props.component.render){
    return props.component.render(props);
  }
  return React.createElement("li", { ref, ...props });
});

** It requires implementing your own styles, theming, closing the menu. But the focus and scrolling works as expected and it is high performance.

If the maintainers are open to it I can expand on the above and open a PR with a MenuItemUnStyled or something similar.

Video of the existing MenuItem with 2000 rows.
https://www.loom.com/share/fa97283e34f443f0b1179a0131cd0e33

Video of MenuItem after the changes above.
https://www.loom.com/share/5b22d317037442e997c3b5fb944a290e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: select This is the name of the generic UI component, not the React module! performance
Projects
None yet
Development

No branches or pull requests