Tuesday, September 10, 2013

querySelector vs. jQuery: Proving Black-Box Testing in Practice

Recently a colleague of mine, Justin Tullgren, made the point on Twitter that jQuery selectors are significantly slower than their (lesser known) native browser equivalents: querySelector and querySelectorAll.  This revelation leads to exactly the sort of changes that black-box testing a view façade allows you to make because it will won't change its behavior even though it improves the process.

To demonstrate, consider the getCheckbox implementation from our example using jQuery.



var result = $('.sample :checkbox:first').eq(0);
  
if (result.length === 1) {
 return result[0];
}
  
return null;
Using a jQuery to select our checkbox and return the DOM element or null

Since querySelector or querySelectorAll only operate on CSS selectors, we need to replace jQuery's :checkbox pseudo-class selector with the pure CSS equivalent of input[type="checkbox"].  We can avoid worrying about the CSS to replace the :first pseudo-class by using querySelector to only return the first element that matches the query.

All together, our replacement for the four lines (depending on how you count them) of code above is just a single line:



return document.querySelector('.sample input[type="checkbox"]');
Using querySelector to get the DOM element for our checkbox with a CSS selector
This does introduce a new dependency into our function which we have to inject or resolve in order to maintain our unit of work's isolation.

Personally, I like how resolving the document reference from the already-injected jQuery dependency means we won't have to change any outside code.


function SampleViewFacade ($) {
 var me = this,
  document = $('body')[0].ownerDocument;
Declaring a new document variable from the ownerDocument of the body

I might try to justify this as my using jQuery as a consistent gateway to the DOM, but mostly I think it's cool!

The end of the story is that we have just introduced a significant cross-browser performance enhancement, while maintaining our application's behavior.

Go ahead and run the tests to prove it to yourself.

Download the code from this article
Browse the source t on GitHub

2 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete

Note: Only a member of this blog may post a comment.