Answer the question
In order to leave comments, you need to log in
How to speed up the search for a substring match?
$('input#searchVariant').on('keyup', function () {
var query = this.value.toLowerCase();
var variants = this.parentNode.nextElementSibling;
var allVariants = variants.querySelectorAll('div.label-point');
allVariants.forEach(function (item) {
if (item.getAttribute('name').toLowerCase().indexOf(query) > -1) {
item.style.display = '';
} else {
item.style.display = 'none';
}
})
});
Answer the question
In order to leave comments, you need to log in
I propose to store allVariants in a variable in memory, and not as DOM elements, and draw everything you need when necessary through
$('input#searchVariant').on('keyup', function () {
вычислить строку по которой искать,
найти нужные элементы в массиве/объекте с данными,
сделать для каждого свой блок
добавить куда надо на страницу
}
At a minimum , cache
var variants = this.parentNode.nextElementSibling;
var allVariants = variants.querySelectorAll('div.label-point');
Then remove .toLowerCase() (it is possible to cache the correspondence between the given name and the DOM tree element somewhere)
According to https://proglib.io/p/javascript-performance-mistakes , simple for is almost 8 times faster than forEach. Another from a series of savings on matches, replacing > with !==
You can use libraries for debounce (for example , https://lodash.com/docs/4.17.11#debounce ) so as not to call processing on each click, but, for example, not more often than once per second.
Well, read about the profiler in the development tools to find out which lines eat the most time. This is where you have to start.
I also thought that you can compare the previous and new input values, and if the new one is more strict (Abyr -> Abyrv), then search not for all, but only for those found at the previous stage. + you need to check if there will be an effect if you do not change the visibility, if it should not change. It is possible that style recalculation still occurs even if we assign the same value to the styles as they are stored.
In general, display without pagination of thousands of elements is somehow strange. So the straight road is further into reactive frameworks, because it's much more direct there than working directly with the DOM. I prefer vue.
It's not the search that slows you down, but the DOM manipulations
. First, replace the comparison > -1 with a strict inequality.
Second, don't use style object manipulation, instead add/remove a class, without having to add/remove a class if it's already in the right state. That is, you need to add a check for the presence / absence of a class.
And thirdly, at the beginning of the function that is called on the "keyup" event, I would stick a check on which button was pressed, there are a number of buttons that make no sense to respond to, for example, punctuation and spaces, I'm sure you will find a couple more = )
<style>.hidden{display:none}</style>
<script>
allVariants.forEach(function (item) {
if (item.getAttribute('name').toLowerCase().indexOf(query) !== -1) {
if(item.classList.contains('hidden')){
item.classList.remove('hidden')
}
}
else {
if(item.classList.contains('hidden') === false){
item.classList.add('hidden')
}
}
})
</script>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question