0

My fellow programmers, i'am losing my mind. I've reed many books on JS performance and all of them were saying, that it is better to cache DOM objects for future references and management and not creating new Jquery objects. It sounds reasonable. But now my faith is shaking. Im trying to develop Code conventions in my company and i was goin to adress this problem from a performance stand point. I've got piece of code that follows:

        $("#registratorType").attr("readonly", "readonly");
        $("#registratorType").attr("size", "25");
        $("#id").attr("readonly", "readonly");
        $("#id").attr("size", "25");
        $("#serial").attr("readonly", "readonly");
        $("#serial").attr("size", "25");
        $("#duration").attr("size", "25");
        $("#stoppingDuration").attr("size", "25");
        $("#speeddata").removeAttr("disabled");

Its not the whole thing but i think, that you've got the idea. I was going to get all this form and wrap it in the cached reference.

    var $form = $('#vehicleProfile');
    $form.find("#registratorType").attr("readonly", "readonly");
    $form.find("#registratorType").attr("size", "25");
    $form.find("#id").attr("readonly", "readonly");
    $form.find("#id").attr("size", "25");
    $form.find("#serial").attr("readonly", "readonly");
    $form.find("#serial").attr("size", "25");
    $form.find("#duration").attr("size", "25");
    $form.find("#stoppingDuration").attr("size", "25");
    $form.find("#speeddata").removeAttr("disabled");

I've tested performance in the latest chrome and was shocked! My approach was losing in 3-4 times. I mean my function runned at 42 ms, while old one was 12-14ms. Is there REALLY any value to my method? Is my approach an anti-pattern? Help me please!

user1929437
  • 453
  • 6
  • 13
  • 2
    That's not what "cached reference" means. – Bergi Feb 06 '13 at 10:12
  • I think it is useless to use in ID selector in `find()`, what you should do is something like var `$registratorType = $('#registratorType'); [...]` – Matteo Tassinari Feb 06 '13 at 10:13
  • Cache the _finds_ like `var registratorType = $("#registratorType");` then use `registratorType.attr()` as the `registratorType` variable is a jQuery Object – andyb Feb 06 '13 at 10:13

2 Answers2

2

Since all your selectors are id selectors, they are reasonably fast (document.getElementById is an O(1) table lookup). Yet, limiting them to a certain parent element with find() makes a DOM tree search necessary, which is an obvious slowdown.

"cache DOM objects for future references" means that you never shall apply the same selector twice. Do it once, and store it in a variable (like you did with $form). So instead of

    $("#id").attr("readonly", "readonly");
    $("#id").attr("size", "25");

it should be

    var $id = $("#id");
    $id.attr("readonly", "readonly");
    $id.attr("size", "25");

Since jQuery allows chaining, the above can also be written as

    $("#id").attr("readonly", "readonly").attr("size", "25");

Btw, you actually seem to want to use prop() instead of attr(), and those functions accept value maps as well:

    $("#id").prop({readonly: true, size: 25});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • You can also pass a map to `.attr()` to set multiple attributes at once: `$("#id").attr({"readonly":"readonly","size":"25"});` (which gives a definite performance improvement if used on a jQuery object that contains multiple elements). – nnnnnn Feb 06 '13 at 10:19
  • So the bottom line is that there's no other drawbacks, besides the uglyness of DOM tree, in addressing elements by id other than those names are being reserved and cant be used in DOM tree. For example if i got 2 similair forms on the page i could just prefix the ID's and get better performance? – user1929437 Feb 06 '13 at 11:31
  • @user1929437: Yes, probably. However, if you do the caching (storing references to the DOM elements in variables) properly so that you do the DOM selection only once in the whole app runtime, you will not notice it. – Bergi Feb 06 '13 at 15:21
1

Because you are finding element by their Ids. All browser have a getElementById and it's the most effective way to get an element.

Retry your benchmark with element identified by class.

Pierre Inglebert
  • 3,858
  • 1
  • 18
  • 22
  • So the bottom line is that there's no other drawbacks, besides the uglyness of DOM tree, in addressing elements by id other than those names are being reserved and cant be used in DOM tree. For example if i got 2 similair forms on the page i could just prefix the ID's and get better performance? – user1929437 Feb 06 '13 at 13:44
  • In theory yes, I read that some browsers have a performance decrease after 500 different ids but I never benched or tried it myself. – Pierre Inglebert Feb 06 '13 at 20:47