HTML5 introduces custom data attributes: non-visible pieces of information associated with a DOM node. This is an extremely convenient feature, especially since these attributes are accessible by both JavaScript and CSS. But what about performance? Is it possible that the use of data attributes will make your application run slower?

Accessing data

Let’s say you have an element that looks like:

<divid="mydiv"data-purpose="greeting">Hello</div>

With HTML5 you can access the custom attribute with

mydiv.dataset.purpose; // "greeting"

For older browsers you need to fall back to using getAttribute():

mydiv.getAttribute('data-purpose'); // "greeting"

DOM is slow

You know that DOM operations are a common bottleneck in dynamic web application, more so than anything you do in ECMAScript land (functions, objects, loops). And these data attributes hang on DOM nodes. Does that mean that reading and writing them in JavaScript can be slow?

Let’s write a JSPerf.com test to find out.

DIY Data utility

In the test we compare the performance of:

  1. using HTML5 dataset
  2. using the fallback old school getAttribute() and setAttribute()
  3. using a do-it-yourself data storage using a small Data object

The Data utility creates one custom attribute __data for each DOM element we’re interested in and uses it as an auto-incremented identifier. The actual data will be stored privately in the Data object’s closure in a warehouse variable:

varData = function(){varwarehouse = {};
  varcount = 1;
  return{reset: function(){count = 1;
      warehouse = {};
    },
    set: function(dom, data){if(!dom.__data){dom.__data = "hello" + count++;
      }warehouse[dom.__data] = data;
    },
    get: function(dom){returnwarehouse[dom.__data];
    }};
}();

(Side note: creating custom (expando) attributes is associated with memory leaks in IE, so it’s a good idea to cleanup all these expandos before you remove the DOM node or unload the page.)

Using this utility looks like:

Data.set(mydiv, {purpose: "greeting"});
Data.get(mydiv).purpose; // "greeting"

The test

You can run the test at jsperf.com/data-attributes.

It uses one DOM node, and writes and reads three data properties using each of the three methods: old school, dataset and DIY.

// old school attributesdiv.setAttribute('data-po', 'to');
div.setAttribute('data-ta', 'ma');
div.setAttribute('data-to', 'to');
vara = div.getAttribute('data-po');
varb = div.getAttribute('data-ta');
varc = div.getAttribute('data-to');

// HTML5 datasetdiv.dataset.po = 'to';
div.dataset.ta = 'ma';
div.dataset.to = 'to';
vardata = div.dataset;
vara = data.po;
varb = data.ta;
varc = data.to;

// DIY Data utilityData.set(div, {po: 'to', ta: 'ma', to: 'to'});
vardata = Data.get(div);
vara = data.po;
varb = data.ta;
varc = data.to;

Results

The results show that using a simple Data utility to store data associated with a DOM node is significantly faster than storing the data in the DOM node. And the results are consistent across browsers.

Using data attributes can be anywhere between 5 to 30 times slower than using a Data object.

data

Interestingly, HTML5 dataset is the slowest, even slower than using getAttribute(), although the big difference really is between a data attribute and a Data object in ECMAScript land.

Takeaways

Using data attributes is convenient, but if you’re doing a lot of reading and writing, your application’s performance will suffer. In such cases it’s better to create a small utility in JavaScript to store and associate data about particular DOM nodes.

In this article, you saw a very simple Data utility. You can always make it better. For example, for convenience you can still produce markup with data attributes and the first time you use Data.get() or Data.set(), you can carry over the values from the DOM to the Data object and then use the Data object from then on.

ABOUT THE AUTHOR

Stoyan (@stoyanstefanov) is a Facebook engineer, former Yahoo!, writer ("JavaScript Patterns", "Object-Oriented JavaScript"), speaker (JSConf, Velocity, Fronteers), toolmaker (Smush.it, YSlow 2.0) and a guitar hero wannabe.

17 Responses to “Efficient HTML5 data- attributes”

  1. yuanyan

    DOM about is always more slower, got it

  2. How to read performance articles | Christian Heilmann

    [...] Stefanov’s “Efficient HTML5 data- attributes” talks about the performance of HTML5 data attributes and that they are slow. We have the [...]

  3. Matt Andrews

    I got curious about jQuery and what it uses internally for this — turns out it’s even slower than the HTML5 dataset.

  4. Zach Leatherman

    @Matt Andrews: Took a hand at updating your test. You’ll want to reuse the $(div) so you’re not testing the speed of the jQuery object, but instead just the data access piece.

    http://jsperf.com/data-attributes/3

    For benchmarking equality, it seems just a tad bit off that some methods would use one set call and others would use three.

    Interesting results! Very surprised to learn that dataset was slower than getAttribute.

  5. Benjamin Eidelman

    this is very interesting, I’m surprised jQuery .data(…) is so slow in comparison,
    Maybe you could send a pull request to jQuery using a similar approach (I actually thought jQuery was doing exactly this).

  6. Joey Hurst

    I think a much more common use case for data attributes is to pass down a tiny bit of element-associated, lazily evaluated, structured data with an initial html document (as opposed to an element-associated client data store, as seen in these tests).

    In that context, read operations are much more important than writes. Unfortunately, the numbers don’t look much better:
    http://jsperf.com/data-attributes-readonly
    … and in particular, I’m surprised that dataset is so much worse than getAttribute, although I think some more thorough comparison testing is needed.

    There are some additional costs associated with DIY Data in this context too (you’d have to actually execute the setter JS snippet somewhere in the document’s scripts, whereas the other techniques require no JS execution for initial setting and can be lazily deserialized from the DOM).

  7. Benjamin Eidelman

    after checking out jQuery, it stores all data in a global object named “jQuery.cache”, so it’s still puzzling why is it so slow.

    jQuery.fn.data function certainly is a bit more complex, but it seems to be following the same logic.

  8. swapnil raja

    Its Awesome ! Thanks for sharing such kind of information

    Html5 Tutorial

  9. Djalma Araujo

    I’ve made a little library based on the concept, may be helpful to someone https://github.com/djalmaaraujo/data-attribute

  10. Denis

    dataset helps you also get data from custom data-* attibutes, as getAttribute() does.

    But your Data implementation doesn’t help you getting this data. Even though is a lot faster, it is not serving the same purpose as the other ones.

    If you want to add this behaviour to your Data implementation you have to use either dataset or getAttribute, may be as a fallback, if the supplied data to get is not in the cached object, try looking for in the data-* attribute. And this way there is a much more better implementation keeping it fast and compatible with HTML5 specs.

  11. http://Www.Issba.org/

    “Performance Calendar » Efficient HTML5 data- attributes” was indeed a wonderful
    article and therefore I personally ended up being very satisfied to discover the article.
    Thank you,Lashawn

  12. http://Primeonlinesolutions.weebly.com/

    I really blog also and I’m authoring a thing related to this excellent blog, “Performance Calendar » Efficient HTML5 data- attributes”.
    Do you really mind if perhaps I personallyuse a lot of of your suggestions?
    Regards -Margery

  13. golf schools in florida

    This post is in fact a pleasant one it assists new the web viewers, who are wishing
    in favor of blogging.

  14. Chiropractor

    Hi! Quick question that’s totally off topic. Do you know how to make your site mobile friendly? My site looks weird when browsing from my apple iphone. I’m trying to find a theme or plugin that might be able to fix this problem.
    If you have any suggestions, please share. Cheers!

  15. floristry jobs exeter

    Good info. Lucky me I ran across your blog by accident (stumbleupon).
    I have book-marked it for later!

  16. http://tinyurl.com/tucsonseo

    Thanks Stoyan, also bookmarked this page. Very helpful since HTML 5 is becoming very popular. I know Facebook focused on it a lot but than pivoted to mobile.

  17. seo miami company website

    The results show that using a simple Data utility to store data associated with a DOM node is significantly faster than storing the data in the DOM node.

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
And here's a tool to convert HTML entities