Save Object States In .data Or Attr - Performance Vs CSS?
Solution 1:
This performance part of the question screams of premature optimization; see below. (Lest you get the wrong idea: I too am frequently guilty of wondering about the same sort of premature optimization question.)
But getting performance out of the way (other points addressed below the graph): As far as I can see, attr
is faster than data
in jQuery 1.7.1: http://jsperf.com/jquery-setting-attr-vs-data This surprises me. Not that it's remotely likely to matter.
Gratuitous bar graph (longer lines = faster performance):
Are there some other reasons you can think of, to use .attr() and not .data()?
At least a couple come to mind:
The advantage of
data
is that it doesn't have to write to the element every time; you only write to the actual element the first time, and from then on jQuery is just updating a value in a JavaScript object it maintains in a separate object cache (connected to the element via a key). (I'm not sure why it's slower thanattr
; perhaps because of the indirection.)One thing I dislike about
data
is that it's not symmetrical: The first time you accessdata
on an element, the data object is seeded withdata-*
attributes from the element; but from there on out, there is no connection between the two.Example (live copy | live source):
var target = $("#target"); display("data('foo'): " + target.data("foo")); display("data-foo: " + target.attr("data-foo")); display("Setting data('foo')"); target.data("foo", "updated data('foo')"); display("data('foo'): " + target.data("foo")); display("data-foo: " + target.attr("data-foo")); display("Setting data-foo"); target.attr("data-foo", "updated data-foo"); display("data('foo'): " + target.data("foo")); display("data-foo: " + target.attr("data-foo"));
Assuming the
#target
element starts out withdata-foo="bar"
, the output is:data('foo'): bar data-foo: bar Setting data('foo') data('foo'): updated data('foo') data-foo: bar Setting data-foo data('foo'): updated data('foo') data-foo: updated data-foo
That can be confusing and surprising. The way you have to think about it is that the
data-*
attributes are default values only. I just don't like how they're so dependent on whether you've calleddata
before or not; unless you never write to thedata-*
attribute directly, you can't be sure what valuedata
will get (the original from the markup, or a value you updated later before you calleddata
). It seems a bit chaotic to me, but if you set yourself rules (never write todata-*
attributes directly and only ever usedata
, for instance), you can avoid the chaos.When you use
attr
, you can only store strings. When you usedata
, you can store any JavaScript value or object reference.
Because performance is always an argument!
Not in 2012. :-) Or at least, it's a lot lower down the list relative to other arguments than it used to be absent a specific, demonstrable performance problem.
Let's look at your runfirst #rp4
results: 10k iterations of attr
took 515ms; 10k iterations of data
took 268ms. That's 51.5 usec (microseconds, millionths of a second) each vs. 26.8 usec each. So you're wondering whether to use data
if it saves you 24.7 usec per operation. Humans perceive things on the order of tenths of seconds. So for it to matter, you have to do this op roughly 4,000 times in a tight loop for a human to notice the difference. That's just not even close to worth worrying about, even in a mousemove
handler.
If you're into that kind of territory (4,000/second in a tight loop), you'll probably want to avoid storing the information on the element at all.
Solution 2:
Given that .data()
is indeed slower than .attr()
on most browsers, but the speed difference is not important in this question, one advantage of data()
over attr()
is that data will automatically coerce data-
attributes to numbers
or to boolean
values if they match.
That means that
<div id="boolean" data-t="true" data-f="false">
will result in boolean runtime value of true
& false
when you run this:
console.log($('#boolean').data('t')); // reports true (not a string)
console.log($('#boolean').data('f')); // reports false (not a string)
and
<div id="number" data-n="123.456">
will result in a number runtime value of 123.456
when you run this:
console.log($('#number').data('n')); // Reports 123.456 (not a string)
attr
on the other hand only works with strings, but will convert value to strings for saving. It will not coerce values when you fetch them.
The choice between attr
and data
depends on the feature you need for a specific example:
- Where I inject
data-
settings from the server into pages, I tend to usedata()
to access them, if only because it is shorter code. - If I need the data to be visible in the DOM, I will use
attr()
to save the values`.
Solution 3:
You may use jQuery.data. It's almost always the fastest. jQuery tries to optimize its function on every browsers, and maximize compability. So with new versions of jQuery, you may gain performance for this function.
This 2nd test gave me jQuery.data
as the winner.
Post a Comment for "Save Object States In .data Or Attr - Performance Vs CSS?"