Optimizing filters

Many of the filters supported by jQuery aren’t part of the CSS specification, so they can’t take advantage of the performance provided by the use of native methods such as querySelectorAll(). For some of them, such as :input:visible, and others, it’s better to first select using a pure CSS selector and then filter using the filter() method. For example, instead of writing

$('p:visible');

you can write

$('p').filter(':visible');

For other filters, such as :image:password:reset, and others, you can take advantage of the attribute selector instead. Imagine you want to retrieve all the reset buttons in a page. You could use the :reset filter writing

$(':reset');

but you can optimize this selection by turning it into

$('[type="reset"]');

In this selection you’re implicitly using the Universal selector that we said you should avoid. To further improve this selection, you can prepend an Element selector as shown here:

$('input[type="reset"]');

During our exploration, you’ve met the position filters and in particular :eq():lt(), and :gt(). Like other filters discussed in this app, they’re jQuery extensions and aren’t supported by CSS. To improve the performance in cases where you need to use them, you can select the elements and then employ the eq() method as a replacement for the :eq() filter. By doing so, you allow jQuery to take advantage of the native JavaScript methods. As a replacement for :lt() and :gt(), you can use the slice() method.

Based on these suggestions, if you want to select the first two list items in a list, you can write

$('#my-list li').slice(0, 2);

instead of

$('#my-list li:lt(2)');

The last optimization we want to mention here concerns the :not() and the :has() filters. In browsers that support querySelectorAll(), the former can be replaced by jQuery’s not() function, and the second can be replaced by jQuery’s has() method.

For example, you can turn

$('input[placeholder!="Name"]');

into

$('input').not('[placeholder="Name"]');

With this last piece of advice, we’ve completed the optimizations applicable to filters. But there’s a last pearl of wisdom we want to share with you.

Don’t overspecify selectors

jQuery relies on a selector engine, called Sizzle, that parses selectors from right to left. This means that in order to speed up a selection, you must be more specific on the right side and less specific on the left. To give you a concrete idea, imagine you want to select all the <span>s having the class value within a <table> with the class revenue. When performing a selection it’s usually better to write

var $values = $('.revenue span.value');

instead of

var $values = $('table.revenue .value');

Because of the previous statement and the example we showed you, you might be tempted to overspecify selectors, especially on the right side. Don’t do it! If the same set of elements can be retrieved with fewer selectors, get rid of the useless parts. Therefore, avoid writing statements like

var $values = $('table.revenue tr td span.value');

if you can select the same elements with

var $values = $('.revenue span.value');

The former statement is harder to read and won’t boost performance.

The advice we’ve given in this section should help you to optimize your selections. Let’s now discuss how to improve the structure of a project by organizing it into modules.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *