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


you can write


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


but you can optimize this selection by turning it into


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:


During our exploration, you’ve met the position filters and in particular :eq(), :lt(), and :gt(). Like other filters discussed in this book, 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




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.