Reputation: 952
I'm trying to optimize my existing products loading time. I have a big list of products to be displayed/hide based on the conditions selected by the user. To simply, I just pick 3 conditions which are product name, size and color.
For example, products are shown based on the dropdown conditions by the user. Referring to the HTML below, if product name is A, column pa, pa1 and pa2 is shown. If additional condition size is 2, then column pa2 and column pa2r are shown. If color is included, only column pa2r is shown. All other products are hidden.
The HTML is like this
<table>
<tr>
<td>Products</td>
<td class="pa">Product A</td>
<td class="pa1">Product A1</td>
<td class="pa2">Product A2</td>
<td class="pa2r">Product A2r</td>
<td class="pb">Product B</td>
<td class="pc">Product C</td>
<td class="pc1">Product C1</td>
</tr>
</table>
Currently my java script has a big switch filtering product names, and multiple if else conditions to check the color and size. Some conditions might override the existing switch for product names, which causing columns to hide at first, then showed during the switch(product names) statement, and hide again in the inner IF ELSE statement. More conditions will be introduced and will complicate the codes, I tested on IE7 is really slow due to the hide/show and toggles.
A few solutions I've found online which could reduce the load including replace show/hide with css({'display':'none'}) or css({'display':'block'}), basically is to optimize the selector which I think is not good enough.
Is there any other good solutions to handle multiple conditions in jQuery?
Upvotes: 0
Views: 1540
Reputation: 4821
I would optimize this by reducing the number of times your DOM is manipulated to a minimum. I would also optimize for faster element lookups.
General stuff
I noticed that your class names are unique. Change them so that each element has an ID and there is a way to get all products via class. IDs are super fast to look up compared to looking up by class name. Here is an example DOM:
<table>
<tr>
<td>Products</td>
<td id="p-a" class="product">Product A</td>
<td id="p-a1" class="product">Product A1</td>
<td id="p-a2" class="product">Product A2</td>
<td id="p-a2r" class="product">Product A2r</td>
<td id="p-b" class="product">Product B</td>
<td id="p-c" class="product">Product C</td>
<td id="p-c1" class="product">Product C1</td>
</tr>
</table>
My example here won't use the fact that ID lookups are fast, but its good to keep in mind anyway.
Now, your jQuery needs to get all of the products: var elements = $(".product");
Next, you need to loop through your elements, deciding of your element can be shown or hidden. This loop could be done like so:
elements.each(function (e) {
if (<showcondition>) {
$(e).show(); //you can also do this in plain javascript to avoid creating a new jQuery
}
else {
$(e).hide();
}
//alternately: $(e).toggle(<showcondition>) would work as well and is smaller.
});
Now, your <showcondition>
is some value indicating whether or not the element should be shown based on the selection, computed on a per-element basis.
A specific thought based on something you implied but may not be true:
Again, this does not use the fact that ID lookups are fast.
If they must select a product before selecting a number and must select a size before selecting a color as you have implied, you can do a very fast comparison like so:
var selectedProduct = functionToGetSelectedProductLetter() || null; //we want this null if not there
var selectedSize = functionToGetSelectedProductSize() || null;
var selectedColor = functionToGetSelectedProductColor() || null;
//your class names seem to have a certain format...let's take advantage of that:
var startsWith = 'p-'; //this could be anything...even a blank string...so long as your products' ids all start with it.
if (selectedProduct) {
startsWith += selectedProduct;
if (selectedSize) {
startsWith += selectedSize;
if (selectedColor) {
startsWith += selectedColor;
}
}
}
elements.each(function (e) {
$(e).toggle(e.id.indexOf(startsWith) === 0); //if the ID starts with our search string, we show the element. Otherwise it is hidden.
});
This obviously won't work if they can select just a size or just a color, but hopefully it gives you an idea of what I mean by "reduce the number of times your DOM is modified". The above example iterates sets the visibility of each element exactly once rather than doing it over and over again. The whole idea is to use some intermediate variable to "buffer" the showing/hiding of the element until the very last moment. Mathematical and comparison operations are relatively cheap compared to DOM changes for thousands of items since each change triggers a repaint..
Upvotes: 1