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

Select Menu Searchable is slow with approx 180 entries #388

Closed
bfgpab opened this issue Jul 5, 2023 · 8 comments
Closed

Select Menu Searchable is slow with approx 180 entries #388

bfgpab opened this issue Jul 5, 2023 · 8 comments
Labels
duplicate This issue or pull request already exists question Further information is requested

Comments

@bfgpab
Copy link

bfgpab commented Jul 5, 2023

Dear Nuxtlabs team,

I have a Searchable Select Menu with around 180 entries. I have noticed that after upgrading to v2.5 (potentially), it became very slow. It takes around 5 seconds to open the search bar. Then the search itself is fast. If I remove searchable attribute, it works fast again, but given total number of option, search function is a must.

Here is my component:
<USelectMenu :model-value="modelValue" searchable multiple :options="adfeaturesStore" option-attribute="text" size="lg" @update:model-value="value => {modelValue = value; $emit('returnFeatures', modelValue)}" :searchable-placeholder="t('titles.search')" />

And my options array looks as follows:
{id: 1, value: "sizcnewborn", text: "Size (clothes): Newborn"}, {id: 2, value: "sizc3t6m", text: "Size (clothes): 3-6 months"}, {id: 3, value: "sizc6t9m", text: "Size (clothes): 6-9 months"}, {id: 4, value: "sizc9t12m", text: "Size (clothes): 9-12 months"}, {id: 5, value: "sizc12t18m", text: "Size (clothes): 12-18 months"}

Could this be a bug as could have weeks back it was working fine? Or is there something that I do incorrectly?

Thanks in advance!

@bfgpab bfgpab added the question Further information is requested label Jul 5, 2023
@andiamvinay
Copy link

I'm running into the same issue. Any suggestions here?

@andiamvinay
Copy link

@benjamincanac Can you please suggest if there is a way to improve the performance here.

@benjamincanac benjamincanac added the duplicate This issue or pull request already exists label Jul 13, 2023 — with Volta.net
Copy link
Member

This is a duplicate of #280, we need to look around useVirtualList.

@bfgpab
Copy link
Author

bfgpab commented Jul 18, 2023

In the meantime I went with a custom build. It does not support Async calls, but works with static data quite OK.
PS:
Styling done with Tailwind CSS
Credits: https://www.digitalocean.com/community/tutorials/vuejs-vue-autocomplete-component

<template>
<input type="text" :placeholder="Start typing" autocomplete="off" v-model="autocomplete.search" @input="Autocomplete()" @keyup="AutocompleteKeyPress($event)" />
<div class="relative">
	<ul class="text-sm w-full absolute top-px bg-white dark:bg-gray-600 shadow rounded-e overflow-hidden" v-show="autocomplete.open">
		<li class="px-4 py-2 border-b dark:text-gray-200 dark:hover:text-white border-gray-200 hover:bg-gray-100 		hover:dark:bg-gray-700" :class="{'dark:text-white bg-gray-200 dark:bg-gray-800' : index === autocomplete.arrow}" v-for="(item, index) in autocomplete.results" :key="item.value" @click="SetAutocompleteResult(item.text)">{{ item.text }}	</li>
	</ul>
</div>
</template>
<script setup>
const props = defineProps({
	modelValue: {
		type: Array,
		default: []
	}
});
const autocomplete = reactive({
	options: [{value: "item1", text: "Item #1"}, {value: "item2", text: "Item #2"}],
	search: "",
	results: [],
	open: false,
	arrow: -1,
	limit: 5
});
// Below function filters options on keypress and limits suggestions to the limit set in autocomplete.limit
const Autocomplete = () => {
	if(autocomplete.search.length > 1){
		let filter = autocomplete.options.filter((item) => {
			return item.text.toLowerCase().indexOf(autocomplete.search.toLowerCase()) > -1;
		});
		autocomplete.results = filter.splice(0, limit);
		autocomplete.open = true;
	} else {
		autocomplete.results = "";
		autocomplete.open = false;
	};
};
// Below function resets the search and executes function to process the selected item
const SetAutocompleteResult = (item) => {
	autocomplete.search = item;
	autocomplete.open = false;
	autocomplete.arrow = - 1;
	// Do something with the selection
};
// Below function handles keypresses
const AutocompleteKeyPress = () => {
	if(event.key === "ArrowDown"){
		if(autocomplete.open && autocomplete.arrow < (autocomplete.results.length - 1) && autocomplete.arrow < (limit - 1)){
			autocomplete.arrow = autocomplete.arrow + 1;
		};
	};
	if(event.key === "ArrowUp"){
		if(autocomplete.open && autocomplete.arrow > 0) {
			autocomplete.arrow = autocomplete.arrow - 1;
		};
	};
	if(event.key === "Enter"){
		if(autocomplete.arrow > - 1){
			autocomplete.search = autocomplete.results[autocomplete.arrow].text;
			autocomplete.open = false;
			autocomplete.arrow = - 1;
			// Do something with the selection
		};
	};
};
</script>

Copy link
Member

Can the newest async search from #426 solve your issue? https://ui.nuxtlabs.com/forms/select-menu#async-search

@9uenther
Copy link
Contributor

It's still just as slow for me. I tested it with a country list from world_countries_lists with

const searchCountry = async (q) => {
    return countries.filter(e => !q || e.toLowerCase().search(q) > -1)
}

same with

const searchCountry = async (q) => countries

I've built a quite special workaround to pick a language out of iso6391. The fullname is a combinationof getName, getNativeName and some country specific stuff. I use the <template #default="{ open }"> slot to design the look of the label.

screencast-2023-07-20 20-06

I also use the standard javascript filter function here.

const languagesList = computed(() => {
    return languages.filter(e => (languageSearch.value) ? e.fullname.toLowerCase().search(languageSearch.value.toLowerCase()) > -1 : e)
})

@wvffle
Copy link

wvffle commented Jul 21, 2023

I have a similar performance issue when it comes to the Select Menu. I have around 200 entries and the hover effect is lagging behind the cursor for half a second.

@benjamincanac: Using a useVirtualList might be a good idea to bump up the speed.

I've tried to implement it myself but that requires a bit of reordering of the HTML structure, so I decided to go back to work. @benjamincanac if you're ok with some template restructuring I could get back to it and create a MR.

@benjamincanac
Copy link
Member

Closing in favor of #280. This should be fixed in #1289.

@benjamincanac benjamincanac closed this as not planned Won't fix, can't repro, duplicate, stale Mar 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants