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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance degrades significantly as number of options increases #94

Closed
rstuart85 opened this issue Aug 29, 2016 · 10 comments
Closed

Performance degrades significantly as number of options increases #94

rstuart85 opened this issue Aug 29, 2016 · 10 comments

Comments

@rstuart85
Copy link

When you pass a MultiSelect component an options list of a couple hundred, everything works as expected and there is minimal lag. However, when you get into the thousands, the component is unusable, even when using it as a basic select.

I've yet to dive into why the performance is so bad as the number of items goes up (it feels like n^2 performance), but I thought it might be good to capture the issue first.

@shentao
Copy link
Owner

shentao commented Aug 29, 2016

This is a known problem among most select libraries. Handling thousands of options is simply heavy. In this case, the initial time will be quite long, as Vue needs to transform and bind all the options. After the bootstraping is done it should be a bit better, but still not good enough.

You either need to use virtualization or limit the number of options displayed. The second idea is actually quite good imo, because why should anyone want to scroll through thousands of options. This is also quite easy to implement, as I would only need to return the first ~100 options that match the search query.

@rstuart85 What do you think about this approach?

@rstuart85
Copy link
Author

@shentao The limiting of options sounds like a good idea.

Without looking at the code myself yet, two things come to mind:

  1. Not allowing people to scroll without first typing and limiting displayed results might be an even better idea. That's an option I'd like.
  2. I'm not convinced that letting people scroll results isn't doable. Implements a view window approach that gets updated in the background might be one idea. But regular select boxes can easily hand 1000s of options, so I'm interested to know exactly what the problem is here.

@shentao
Copy link
Owner

shentao commented Aug 31, 2016

@rstuart85
2) A regular select box can handle more options because well... there is no additional computation involved in showing each of the options. On the other hand in Multiselect, there is more work involved. Vue has to transform the whole options array, iterate through it dynamically creating the DOM elements, event handlers and so on – this takes the most time.
If I understand correctly, what you mean with updating it in the background is creating a solution based on virtualization (like clusterize.js).
This will obviously solve the problem of handling many thousands of options, but for what purpose? I believe that putting thousands of options inside a dropdown is just bad design and this is the place where it should be fixed. UX-wise such long options list aren’t probably the best solution for users.
So this is doable, but I guess in most cases this won’t be used by other devs. And implementing it would slow down the execution of simpler cases and increase the complexity and size of the library itself.

  1. This is something that can be implemented really cheap if we want to handle it inside the Multiselect component as a new config option.
    However, the same can be achieved without actually changing anything in the current code at all. What you would need to do is just handle the @search-change event and based on it, filter the available options and only pass like the first 100 back to Multiselect. Just like in the Async Example, but without the actual async part. 😃
    If you want to not display anything where there is no search query, just let the filter function return an empty array when search equals empty string.

Would the work for you, at least for now?

@shentao
Copy link
Owner

shentao commented Sep 11, 2016

Ping @rstuart85 :)

@rstuart85
Copy link
Author

@shentao Will get back to you on this shortly.

@shentao
Copy link
Owner

shentao commented Sep 18, 2016

You can now pass the options-limit prop, which expects a Number and is, by default set to 1000.
Published and available in v1.1.3! Should be in the docs in a moment.

shentao pushed a commit that referenced this issue Sep 18, 2016
@johannes-z
Copy link

@shentao What about using a library such as https://github.com/tangbc/vue-virtual-scroll-list? This would require a custom template (scopedSlot) for the wrapper ul too, not just the options themselves.

@Edza
Copy link

Edza commented Mar 26, 2018

@johannes-z Did you attempt to use the vue-virtual-scroll-list with this multiselect? What were the results?

@shentao
Copy link
Owner

shentao commented Mar 26, 2018

@johannes-z I’m currently working on the 3.0 release which should be much more flexible and allow for virtual-scrolling among other things.

@Jettonn
Copy link

Jettonn commented Apr 5, 2022

@shentao When is going version 3.0 to release, since Vue 3 is the default version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants