What is the efficient way to create a live search using javascript or jquery? -
i making live search more 10000 rows of dataset. have mentioned available dom structure. although try make live search check every result after single input, browser getting hang. there other efficient way can reduce complexity.
<label class="label"> <input type="checkbox" name="123" value=""> </label> <label class="label"> <input type="checkbox" name="123" value=" general aux"> general aux </label> <label class="label"> <input type="checkbox" name="123" value=" annser"> annser </label> <label class="label"> <input type="checkbox" name="123" value=" lripl"> lripl </label> <label class="label"> <input type="checkbox" name="123" value=" soy impulse"> soy impulse </label>
** yes, live search against dom** js code, using live search
$(".form-container #filter").keyup(function() { var filter = $(this).val(), count = 0; if(filter.length>=2){ // loop through comment list $(".label").each(function() { // if list item not contain text phrase fade out if ($(this).text().search(new regexp(filter, "i")) < 0) { $(this).fadeout(); // show list item if phrase matches , increase count 1 } else { $(this).show(); count++; } }); // update count var numberitems = count; // $(".popopup-header").text(count + " results"); //$("#filter-count").text(count + "results"); } });
there 3 different ways can improve performance of live dom search. (i'm going take inherent performance issue rendering 10000 dom rows given; answer cover search , results.) small details such using .indexof() instead of regexp well, i'd guess sort of fine detail not bottleneck.
make search faster
live-searching dom going much, slower searching against simple data object. i'm going guess is, far, biggest performance bottleneck have.
it looks you're matching against single string per row, makes things easier. if can depend on order of rows never change, away searching against simple array of strings, , use array index indicate dom rows you'll hide or reveal (more later) -- if row order may change, you'll need include @ least id each can match string correct row. simplest case might be
var search = function(searchstring) { var searchablerows = ["general aux", "ansser", "etcetera", ...] var matchedsearch = []; (var i=0; i<searchablerows.length; i++) { if (searchablerows[i].indexof(searchstring) > -1) { matchedsearch[i]=1; } } // you'll use matchedsearch[] later control rows visible.
run search less often
instead of running search on every user keystroke, can debounce input guarantee @ least n milliseconds between individual searches. frameworks have debounce functionality built in, it's pretty simple roll own. canonical drop-in example this david walsh, cannot improve on:
// returns function, that, long continues invoked, not // triggered. function called after stops being called // n milliseconds. if `immediate` passed, trigger function on // leading edge, instead of trailing. function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callnow = immediate && !timeout; cleartimeout(timeout); timeout = settimeout(later, wait); if (callnow) func.apply(context, args); }; };
render results more quickly
one big dom operation less expensive lots of little dom operations. , less have change dom results want, better.
so simple approach of incrementally hiding or removing dom rows during search -- that's out sure. 2 approaches can think of handle different, , i'm not sure have better performance; better may come down other factors such how complex html needs , whether has js bindings need preserve, how of you're comfortable generating within javascript, etc.
so strategy 1: generate results html 1 big string , drop dom replace original html in single operation:
//assuming have filled matchedsearch array above: var searchresults = ""; (var i=0; i<searchablerows.length; i++) { if (matchedsearch[i]) { searchresults = searchresults + '<label>...'+searchablerows[i]+'</label'>; } } document.getelementbyid('resultslocation').innerhtml(searchresults);
or strategy 2 take opposite approach: render full list once, , minimize how change after fact each search. again, after you've finished generating matchedsearch array:
var alllabels = $('.label'); // i'm being lazy , depending on jquery in example (var i=0; i<alllabels.length; i++) { if (matchedsearch[i]) { alllabels[i].removeclass('hidden'); } else { alllabels[i].addclass('hidden'); } }
(there other possible optimizations in how display -- note you're using .fadeout()
currently; off top of head i'm not if that's slower using css class-based animation, it'd worth checking. many rows might consider omitting unnecessary visual flourishes anyway.)
Comments
Post a Comment