What is the best option to use in relation to performance

Asked

Viewed 73 times

1

I need to make all products disappear from the screen, but I have products that are no longer on the screen. So my question is: If I hide only the products that are visible will perform better? instead of giving a .hide() in all products, even those that are already invisible

For example, what would be the best performance of these two code snippets below

$(".produto").hide().attr('invisible',true);

OR

$(".produto[invisible=false]").hide().attr('invisible',true);

3 answers

2

Warning: Unfortunately the jsperf, that would be the most practical tool to test what I say in my reply, has had stability problems, and I’m having trouble using it at the moment. So consider that some of my arguments can be either confirmed or disproved by a real performance test. And don’t forget that the best option may vary according to the browser.

To understand the possible performance bottlenecks in these code snippets, let’s see what operations they perform:

  1. $(...)- Creates an array of jQuery objects containing all elements that fit the past selector. Whenever possible jQuery uses the native function document.querySelectorAll for that reason.
  2. .hide() - Loop over our array of elements, hiding them all, one by one.
  3. .attr('nome', valor) - Executes another loop over the array, setting the attribute value for all of them, one by one.

The difference between your two code snippets is in the operation 1, but may impact the other two.

In theory, select only the elements of a class (such as ".produto") is faster than selecting the elements of this class that meet any additional criteria (such as ".produto[invisible=false]"). But this may depend on how the selection algorithm is implemented in each browser. And, also in theory, selecting attributes is slower - which also depends on the implementation.

But assuming that the first selector is actually faster, and the other operations (the loops) are the same in the two snippets of code that you posted, then the first version is faster than the second, right? Not necessarily! The first version has the potential to select more page elements, since it is less restrictive than the second, and this can influence the execution time of the loops.

Imagine a page with many products (I don’t know, 5,000), but only 10 visible. The first version can even select faster, but it will select 5,000 elements, and then iterate over those 5,000 elements twice. Already the second would select only 10 elements, and make 2 loops on these 10, which theoretically is much faster and can compensate for the greater slowness of selection.

Completion

In performance issues like this, the only way to do a realistic test is to reproduce all the conditions of your application, and see how each variation behaves. What matters is how they behave in these situations, not in any possible situation. And if you test the two variations in your application, with real users, on the various browsers that you intend to support, and both of them turn out well, forget about the performance issue. The cost (in time, effort) of micro-optimizations of this type is much higher than the performance improvement they may provide, and that is generally negligible.

1

The first will be executed faster, since it will only be necessary to find all elements with product class, while the second code will have to find those same elements and then check its attribute Invisible.

1


Single selectors as .produto will always be faster than complex selectors to search for

But to change properties is likely to [invisible=false] is faster, since changing DOM elements that are already in the body of the page is more costly, then in this case the query will bring less elements and this will make the process with .hide faster, because we will have fewer elements.

Classes and performance

However, class query is usually faster than attribute query, so instead of using .attr('invisible',true); use a class, such as:

Conceal:

$(".produto:not(.hide)").addClass("hide");

Displays:

$(".produto.visible").removeClass("hide");

If you want to use the animated effect:

$(".produto:not(.hide)").hide(400, function() {
    $(this).addClass("hide");
});

$(".produto.hide").removeClass("hide").show();

However note that this type of optimization is minimal.

Selector :hide and :visibile

Selectors can also be used :hide and :visibile may be useful, for example:

$(".produto:visible").hide();

and

$(".produto:hide").show();
  • 1

    Following this idea of using a class for visible and another to invisible gained 2 seconds of performance at the time of executing code :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.