-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
Select: Performance improvements when opening menu and when hovering over options #69230
Conversation
I agree with your decision here. It would be more bad to have this interaction differ across Grafana. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvement. Tested this in the Virtualised story (by bumping the generateThousandsOfOptions
up to 100,000), and with the Prometheus query editor and while this doesn't solve all problems (initial open is still a bit slow, typing isn't super responsive), it ups the performance from unusable to slightly tolerable, which is a bit improvement!
Would be good to get review from others, such as @grafana/observability-metrics on this as well!
I think the next step after this should be to virtualize-by-default. Might want to control this via a feature flag first (just to be safe). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes look good, working for me locally. Thanks for taking the time to improve this component!
What is this feature?
While investigating performance issues with our current Select component, there were 4 different interactions that were slow to the user (#69132). This feature addresses 2 of those performance issues:
Before, when hovering over an option in a very large list (300000 in this case) there was a visible lag and in the profiler we can see a "long task" (in red) for opening the menu and then another "long task" for each of the hovers that it picks up:
Screen.Recording.2023-05-29.at.14.50.27.mov
After, there is no lag and only one "long task" left for the opening of the menu:
Screen.Recording.2023-05-29.at.14.49.20.mov
This one does not solve it completely, as there are issues with react-select itself and how it renders and calculates which options to have on the list (there is an issue on the react-select repo JedWatson/react-select#3128).
What this does is that when the
inputValue
is falsy (for instance''
on first open), it passes thefilterOptions
function asnull
, which means it just shows all the options. Then when there is aninputValue
it sets thefilterOptions
function back. This does improve performance as can be seen in the next video, when we try to open the current virtualized list with 300000 options it takes approximately 2.5s, but the one withfilterOptions={null}
"only" approximately 1.7s.Screen.Recording.2023-05-29.at.15.56.00.mov
Why do we need this feature?
There have been several issues discussing the performance of the select component when there are thousands+ of options (see https://github.com/grafana/observability-metrics-squad/issues/47 or #57675). This improves the performance in the two cases mentioned above.
Who is this feature for?
Users using selects with very long lists
Which issue(s) does this PR fix?:
Fixes partly #69132
Special notes for your reviewer:
There is 1 known loss in functionality here. Previously, while a user is hovering over an option, it was possible to press "enter" or "tab" to select that option, while now if they do press "enter" or "tab" it will be the option that is focused with the keyboard that will be selected. We could make the "hovering fix" only happen via prop, or only when there are more than a certain number of options, but I don't think this is a severe lack of functionality to warrant another prop to the already 50+ that
Select
has. Worth hearing if other people have different opinions.If there is any other regression in functionality please let me know!
Please check that: