Marvin3
Marvin3

Reputation: 6051

Performance of adding CSS class & number of children

I need to dynamically apply some styling to elements .child-1 and .child-2 by adding CSS classes.

Should I add them once to #parent or to each .child-? If I add it to #parent would existence of #large-container affect the performance?

<div id="parent">
    <div class="child-1"></div>
    <div class="child-2"></div>
    <div id="large-container">
       <!-- a bunch of content here - p tags, images... -->
    </div>
</div>

(.child-1 and .child-2 are absolute positioned elements on top of #large-container)

$('#parent').addClass('myClass1 myClass2');
vs
$('.child-1, .child2').addClass('myClass1 myClass2');

Same with just CSS:

.myClass1 .child-1,
.myClass2 .child-2 {
  color: red;
}
/* vs */
.myClass1.child-1,
.myClass2.child-2 {
  color: blue;
}

myClass1 myClass2 only apply styles to #child-1 and 2, they don't add any styles to #large-container.

Thank you for advice!

Upvotes: 0

Views: 320

Answers (1)

abbood
abbood

Reputation: 23558

although i think my answer is impossible to verify from a profiler (are there any css/html profiling tools out there in terms of rendering the page etc?) I'll state it based on my experience:

$('#parent').addClass('myClass1 myClass2'); 

is faster than

$('#child-1, #child2').addClass('myClass1 myClass2'); 

simply because you are traversing the dom tree once rather than twice ie $('#child-1, #child2').addClass('myClass1 myClass2'); is the same as

$('#child-1).addClass('myClass1 myClass2');
$('#child-1).addClass('myClass1 myClass2');

to theoretically prove that last point imagine your html code looked something like this:

<div id="parent">
    <div id="child-1"></div>       

    ... lots and lots of html nodes 

    <div id="child-2"></div>

</div>

then looking for #child-1 is a completely separate operation than looking for #child-2.. and when it comes to css/html optimisation.. one of the most expensive operations is the DOM tree traversal.

in the case of $('#parent').addClass('myClass1 myClass2'); you are traversing the DOM tree once (ie finding where #parent is then using css cascading to apply to the elements within the narrowed down #parent DOM subtree

to address the concern that @tMagwell raised about repainting #large-container here is another optimized way of applying css:

// store the child-1 node in a variable.. ie whenever you 
// refer to it in the future.. you won't have to traverse the entire DOM again
var child1element = $('#child-1');  
$('#child-1).addClass('myClass1 myClass2');
// referring to child1element costs you nothing big, it's already stored in a variable
child1element.siblings().addClass('myClass1 myClass2');

this code works of course assuming that there are only child-1 and child-2.. if you got child-3, child-4.. child-n and only want to apply it to child-n.. then you can use child1element.siblings()[n] // where n is the index of the child you want to target, since siblings() returns an array

hope this helps!

update:

to address this specific point you raised in the comments:

Does the presence of #large-container slows down something when I add classes to #parent?

the answer is yes. let me give you a scenario where it definitely does:

css:

#parent .class1 .class2
{
  font-size:10pt;
}

html:

<div id="parent">
    <div id="child-1"></div>       
    <div id="child-2"></div>
    <div id="large-container">
      <!-- images etc -->
      <p>hello world!<p>
       <!-- many more p tags that has a lot of text and stuff -->
    </div>
</div>

so in this example.. the font-size:10pt placed under #parent .class1 .class2 will definitely impact the contents of #large-container.. and the operation costs something.. i have no way to quantify how expensive that is (it would depend on the browser rendering engine etc).. but suffice it to say that there is some cost x that is higher than if you didn't just add class1 and class2 to the parent div.

Upvotes: 1

Related Questions