Darcy ClarkeDevelopment / Design / UX

Toggle Main Navigation

Sep 28, 2011

Live vs. Static Node Lists

Posted in "development"

A little while ago, I was working on an application where I wanted to cache collections of elements to save on DOM traversals / improve performance. The problem with caching a collection of elements is that you'll, in most cases, store a static node list. Thus, when new elements are introduced to the DOM, that match your selector, they won't be included (unless you re-query the DOM).

JavaScript frameworks, like jQuery, return static arrays of elements by default. So, if you're using a JavaScript framework, you'll be well acquainted with either: re-querying the DOM, or using methods like .live() or .delegate(). That said, there are some native query methods you can use that will return live node lists.

document.getElementsByTagName(), document.getElementsByTagNameNS and document.getElementsByClassName() are the only options available that return "live" node lists. Looking at those methods, you may be discouraged, but don't be. The returned is a live node list so all subsequent children of those elements will also be updated automatically. This means we can setup a live node list selector, that updates automatically, and then find the elements we'd like to use when ready.

Note: I'm not suggesting storing the whole body as a live node list but a more refined selection. Although, I guess, you could do that if you were so inclined. var cache = document.getElementsByTagName('body'); vs. var cache = document.getElementsByTagName('ul');

Here's an example of a live node list in use:

<iframe style="width: 100%; height: 500px; border: 1px solid #ccc; padding: 3px;" src="http://jsfiddle.net/darcyclarke/sNL5f/3/embedded/"></iframe>

So the key here is that we've moved away from re-querying the DOM and instead simply filtered our stored node list (which was the var test.ul = document.getElementsByTagName(&#39;ul&#39;);).

Another example I put together demonstrates the difference between a selection made with a JavaScript library like jQuery (and their Sizzle Selector Engine) verse a, rather basic, native selector method.

<iframe style="width: 100%; height: 500px; border: 1px solid #ccc; padding: 3px;" src="http://jsfiddle.net/darcyclarke/e6Sa6/embedded/"></iframe>

Of course, we need to factor in the robustness of a selector engine, such as Sizzle JS, compared to the simple document.getElementsByTagName(). The tradeoffs of each will come down to your individual scenario/use-case. Either way, it's good to know how you're interacting with the DOM and what options you have.

Note: Unfortunately, the latest query method, document.querySelectorAll(), was developed and standardized to return a static node list (booo!). Otherwise, this would be the ideal native method.