Choices-js / Choices

A vanilla JS customisable select box/text input plugin ⚡️
https://choices-js.github.io/Choices/
MIT License
6.19k stars 610 forks source link

Dropdown list items rendered multiple times when bulk adding options #178

Closed adamsro closed 2 months ago

adamsro commented 7 years ago

It seems that render() is called every time a choice is added and render removes all innerHTML DOM elements from the dropdown and recreates the list leading to poor performance with large sets, O(n2).

setChoices calls _addChoice in a loop which in turn calls store.dispatch and store calls render on every state change.

The pattern seems to look like: render 1 - clear - render 1, render 2 - clear render 1, render 2, render3

jshjohnson commented 7 years ago

Hey!

There is certainly room for improvement here. There is also going to need to be a loop within the render() method but I'm wondering whether it would be better to dispatch to the store with a bulk of data...

adamsro commented 7 years ago

Hi! Idk, the bulk dispatch seems to make the most sense to me, ADD_CHOICES and REPLACE_ITEMS or something. I like the idea of only making one call to update the state per user/api interaction. If render is only called once there's less reliance on the state checks within the function.

adamsro commented 7 years ago

Using https://github.com/google/incremental-dom or https://github.com/patrick-steele-idem/morphdom Mmight be a nice way to improve rendering performance (less GC), particularly while searching since many choice results will remain the same as more search characters are added?

flying-sheep commented 6 years ago

any updates here? Choices quadruples my app’s loading time.

stale[bot] commented 5 years ago

Thanks for contributing to this issue. As it has been 60 days since the last activity, this issue is being automatically closed. This is often because the request was already solved in some way and it just wasn't updated or it's no longer applicable. If that's not the case, please do feel free to either reopen this issue or open a new one. We'll gladly take a look again!

flying-sheep commented 5 years ago

please add the pinned label or whatever makes @stale shut up.

jshjohnson commented 5 years ago

I've got a functioning work-in-progress of Choices using morphdom. Would be great if somebody could take it for a spin. The branch name is integrate-morphdom

flying-sheep commented 5 years ago

looking good! sadly I have not time to compare times, so how much did they improve?

if you e.g. provide 10000 choices to select from, the JS needed a few seconds to execute before. is that zippy now?

nilsschmidthamburg commented 5 years ago

Hi there, first of all: Thanks for the great work!

I just tested the integrate-morphdom branch to see if it is beneficial for our performance problems with choichesjs. I cannot say that it solved our issues. Maybe the search and update is faster. But adding a lot (aprox. 2000 Items) via setItems on an initially empty list still takes several seconds. I didn't have time (nor the skills) to look deeper into this, but its pretty easy to reproduce like this:

const data = [...Array(1000).keys()].map(value => ({value, label: `${value}`}));

    // Pretty fast
    new Choices(element, {choices: data});

    // Very, very slow
    new Choices(element).setChoices(data);
flying-sheep commented 5 years ago

@stale no