Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuerys $.data() vs. DOM Object property

I recently needed to append some data to dynamically created LI elements. In my first instance, I used .data() in a way like

var _newli = $('<li>foobar</li>');
_newli.data('base', 'ball');
// append _newli to an `ul`

that.. was terribly slow. This logic happens in a loop which can easily grow up to 500+ items, it took ages! Sometimes it even broke the javascript execution time frame.

So I changed to $.data(). Somehow, attaching data to an object with that is like 8x faster than doing it over the .data() method call. So now it looked like

var _newli = $('<li>foobar</li>');
$.data(_newli[0], 'base', 'ball');
// append _newli to an `ul`

That was/is indeed faster, but still it took like 3-4 seconds(!) to build up all my elements (In my real code there are like 6 calls to $.data per element).

So I was really stuck with that, I asked myself why the heck to use .data() or $.data() anyway? I could just attach my data to the DOM object. So I did

var _newli = $('<li>foobar</li>');
_newli[0].base = 'ball';
// append _newli to an `ul`

Voila, wow to my shock, that was incredibly fast! I couldn't believe that this ran so good without any disadvantage. So that is what is my question all about actually. I didn't find any disadvantage for this technique so far on the net. There are reads about circular references you can create using this way, but AFAIK "only" on IE's and only if you refer to objects.

Any thoughts experts ?

update

Thanks for the good comments and postings guys. Short update @patrick dw:

You are right, I was passing the underlaying DOM element when using $.data(). It does not even work with jQuery objects, at least not as expected. The idea about using one object and pass it through $.date() I had myself, but then again I was so shocked about the performance difference I decided just to ignore the .data() method like forever.

like image 719
jAndy Avatar asked Aug 04 '10 16:08

jAndy


1 Answers

You are correct about circular references, that isn't an issue outside of IE, and in IE it only becomes an issue when JavaScript has a reference to a DOM object, and a JS object is assigned to one of the DOM object's properties. I believe this can be resolved by simply by nullifying any references in JS to the DOM object.

The $().data() method is an overly complicated wrapper for $.data() (see jQuery.fn.data: http://github.com/jquery/jquery/blob/master/src/data.js#L126, which in turn calls jQuery.data: http://github.com/jquery/jquery/blob/master/src/data.js#L20), so cutting out that middle man will save a non trivial amount of time, especially if it's to be done 500 times.

In this case, the $().data('foo', 'bar') method doesn't do much more than el.foo = 'bar'. Do what's fastest.

like image 137
Ryan Tenney Avatar answered Sep 21 '22 04:09

Ryan Tenney