Vue-select: Slow hover performance on large list of options

Created on 29 Nov 2019  路  10Comments  路  Source: sagalbot/vue-select

First of all, thanks for all of the work on vue-select! We were using some other dropdown options and the performance and interface to vue-select was pretty nice, slots especially were nice to work with (compared to Semantic UI).

Is your feature request related to a problem? Please describe.

https://codepen.io/ckcollab/pen/bGNbBpm

I'm trying to render a list of ~10k items into a dropdown, vue-select, and scrolling performance is good. However, when I hover over items in the dropdown to select one, the hovered item styling seems laggy?

Describe the solution you'd like
For the mouse hover events to be triggered instantly for even large 20k long lists, but this may not be practical.

Describe alternatives you've considered
We've tried vue virtual scroller, which has great performance, but does not behave like a dropdown necessarily.

performance released

All 10 comments

An update on this: I did some profiling in Chrome, and it looks like "hitTest" is taking up a ton of compute time. It's probably iterating through each option in the dropdown to determine if the mouse is over it .. ? Hopefully that's a useful piece of information to someone!

One solution I've seen is to put an overlay on top of the dropdown items, and then yourself interpreting which option is hovered and applying hover effect... that seems like overkill/difficult

Ah that makes sense.

https://github.com/sagalbot/vue-select/blob/3f5872c3fc08c7b24319034e5eab598bd1c4d729/src/components/Select.vue#L56-L64

There's a @mouseover event on the list item to set typeAheadPointer to the currently hovered option.

Ah, I see. Is there a way to disable this? If not, I could try to throw some time at setting this up locally and removing that attribute to see if it significantly speeds things up?

There鈥檚 not currently a way to disable it. I wonder though if you could disable pointer events with CSS? Could be a decent workaround for now.

I鈥檓 working on v4 that significantly overhauls the scoped slots available, and in that case you鈥檇 be able implement the slot and not bind the mouse over.

However, there is a bug in Vue that will cause any default slot content to be run in addition to whatever you鈥檝e overridden the slot with, so using slots will actually hinder performance even more until that鈥檚 fixed.

If you do have some time to do some testing I鈥檇 appreciate the feedback.

I tried a few things with disabling the pointer-events and ultimately, the lag was still there. The time it takes to render the dropdown on click makes me think it's not the primary cause of the slowdown. I pulled the background-color and color off the vs__dropdown-option--highlight because I didn't think it looked great having a highlighted item when you can't select them via hover.

I think a possible solution involves adding an observer based on which elements are showing inside the dropdown at a given time and then rendering those while hiding the rest, but I was struggling to get that working.

Here's a pen of the dropdown with pointer-events: none; on the vs__dropdown-option.

https://codepen.io/brendanmyers88/pen/yLyygjO

@sagalbot do you have any plans to add support for virtual scrolling?

Hello, I've made a pull request for two option that greatly improve performances on huge lists : https://github.com/sagalbot/vue-select/pull/1042

Feel free to review / comment

:tada: This issue has been resolved in version 3.9.0 :tada:

The release is available on GitHub release

Please consider sponsoring Vue Select, your support is much appreciated! :+1:

Eventually I may have first party infinite scroll baked in, but it's implementable in a wrapper component now.

https://vue-select.org/guide/infinite-scroll.html

Was this page helpful?
0 / 5 - 0 ratings