Javascript - Fastest way to show and hide lots of list items

喜你入骨 提交于 2019-12-05 00:16:11


As the user pans around a Google Map, a list of of currently visible markers is updated. This list contains up to 1000 items, and it slows down when several hundred li's are shown or hidden all at once. It's less than half a second, but it's getting annoying.

An array (newLiList) contains the items which should now be visible. Another array (currentLiList) has the items which were previously visible. Both arrays contain the ids of the li's as indexes.

for (var i in newLiList) {
    if (currentLiList[i] != true) {
        $("ul#theList li#"+i).show();
for (var i in currentLiList) {
    if (newLiList[i] != true) {
        $("ul#theList li#"+i).hide();

Is there a faster way to do this?


You could store the <li> elements in an array directly so you don't have to do hundreds of CSS selector lookups. Then instead of $("ul#theList li#"+i) you just do liArray[i].

FYI, "ul#theList li#<i>" is equivalent to just "#<i>" since element IDs are (supposed to be) unique. You don't need the extra context.


For every single .show() and .hide() function call, you're causing a redraw in the browser.

Setting the whole list to display none before you change the list items will prevent the browser from having to recalculate the flow of the document every time, and then you could set the list back to block.

Alternatively, if you don't want the flicker of the list disappearing, you could clone the list, make all the items hide that should hide, and then replace the old list with the new.


You should try caching your selector and using context:

var targetList = $("ul#theList");

and replace:

$("ul#theList li#"+i).show();


$("#"+i, targetList).show();

That'll reduce the amount of times jquery has to bounce around the entire DOM.


You could try hiding the list while you reset all the list items. It might prevent some redraws.

Also, consider just using

$("ul#theList li#"+i).attr("display","none");

$("ul#theList li#"+i).attr("display","block");

rather than hide() and show() since they can take a speed parameter for fancy animation. I don't know if they are any slower if you don't use it, but it's worth checking.


Have you profiled your code?

Never assume which part of the code is running slow, profile the code in FireBug (Assuming you are using Firefox) and tweak the code which is running slower.


Most likely this is slow because you are asking jQuery to traverse the DOM several hundred times. If you instead made a string with all the Ids seperated by comma you could select and hide/show them all in one action.

Let me clarify a bit what I meant, since if you just do $(string_of_elements) jQuery will of cause traverse the entire DOM for each element.


Using this syntax, jQuery will first find the ul element and then only have to traverse it to find the li elements. Now if you have both lists converted to a string, you can do some really neat stuff:


Using this syntax and chaining the two events has another advantage. The actual showing and hiding will happen all at once, rather than it being a one by one hiding and showing.