CSS Performance Between Class and Attribute Selectors

CSS Performance between class and attribute selectors

There is no performance issue. Both act same. But there is difference in specificity of the css with class versus Elements.

Specificity - Specificity determines, which CSS rule is applied by browsers.

If two selectors apply to the same element, the one with higher specificity wins.

But specificity has hierarchy.

  1. Inline styles (Presence of style in document).
    An inline style lives within your XHTML document. It is attached directly to the element to be styled. E.g.
  2. IDs (# of ID selectors)
    ID is an identifier for your page elements, such as #div.
  3. Classes, attributes and pseudo-classes (# of class selectors).
    This group includes .classes, [attributes] and pseudo-classes such as :hover, :focus etc.
  4. Elements and pseudo-elements (# of Element (type) selectors).
    Including for instance :before and :after.

Source: http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/

Hence div.test {} is more specific.

Are data attribute css selectors faster than class selectors?

I wouldn't call it conclusive, but it does appear class selectors are faster... I just put this together for a quickie test.

http://jsperf.com/data-selector-performance

EDIT:

Based on Vlad's and my jsperf tests... if performance is a concern (especially IE)... classes are still the way to go

Are there any performance (or otherwise) differences concerning attributes vs. classes?

Someone created a performance test for an answer to a similar stack overflow question.

http://jsperf.com/id-vs-class-vs-tag-selectors/2

Looks like class selectors are much faster than attribute selectors, though apparently the amount changes depending on the browser.

Are attribute selectors still less efficient than class selectors if we're targeting many classes?

It turns out that this varies on page load, browser, etc. We tested the difference using http://stevesouders.com/efws/css-selectors/csscreate.php

Is it better to use class selectors or custom attribute selectors with jquery?

I would use class selectors. Using custom attribute selectors would be:

  1. Invalid HTML. HTML only permits certain named attributes to be present on certain types of elements.
  2. Slower. While jQuery can use native .getElementsByClassName in your first snippet, it can't for the second. This could lead to a slowdown in modern browsers.

CSS Performance, #id vs .class vs [^regex$] vs selector

Per Eoin's request, I'm making an answer for future visitors (as I think this is useful).

From this link: https://www.sitepoint.com/optimizing-css-id-selectors-and-other-myths/

The following snippet runs on 50,000 nodes. The console output will give you an answer on performance for specific selectors.

const createFragment = html =>  document.createRange().createContextualFragment(html);
const btn = document.querySelector(".btn");const container = document.querySelector(".box-container");const count = 50000;const selectors = [ "div", ".box", ".box > .title", ".box .title", ".box ~ .box", ".box + .box", ".box:last-of-type", ".box:nth-of-type(2n - 1)", ".box:not(:last-of-type)", ".box:not(:empty):last-of-type .title", ".box:nth-last-child(n+6) ~ div",
];let domString = "";
const box = count => `<div class="box"> <div class="title">${count}</div></div>`;
btn.addEventListener("click", () => { console.log('-----\n'); selectors.forEach(selector => { console.time(selector); document.querySelectorAll(selector); console.timeEnd(selector); });});
for (let i = 0; i < count; i++) { domString += box(i + 1);}
container.append(createFragment(domString));
body {  font-family: sans-serif;}
* { box-sizing: border-box;}
.btn { background: #000; display: block; appearance: none; margin: 20px auto; color: #FFF; font-size: 24px; border: none; border-radius: 5px; padding: 10px 20px;}
.box-container { background: #E0E0E0; display: flex; flex-wrap: wrap;}
.box { background: #FFF; padding: 10px; width: 25%}
<button class="btn">Measure</button><div class="box-container"></div>

processing speed difference between CSS class and id

https://web.archive.org/web/20190901050026/http://oli.jp/2011/ids/

ID's are faster in some cases, but not all

It’s a common belief that ID selectors are the fastest, but this comes with a big caveat: IDs are fastest CSS selector only if they’re the key selector. What’s that? Well, while you probably read selectors from left to right, browsers read them from right to left.

There's also a performance test here for your numbers request: https://web.archive.org/web/20190901050026/http://oli.jp/2011/ids/#table1

Conclusion

ID's used correctly are faster, but with such a minimal difference vs classes - it's not worth any consideration.

It seems to me that there are no convincing reasons to use IDs in selectors for CSS styling¹, as CSS classes can do everything IDs can. Hopefully you’ll agree there are some good reasons not to. Think about it the next time you start a personal project or redesign your own site, and try adding a class (or ARIA landmark roles) for styling instead. Save IDs for fragment identifiers or JavaScript hooks

Why are selectors such as a[title=home] slower than using class?

Browser implementors optimize the most common cases. Since classes are used very frequently to match styles, they must implement this as efficiently as they can. When they load in CSS, they index the classes to make this possible.

Since random selectors like title="home" are not used very frequently, they can get away with implementing them using simpler searches. It won't have as much impact on performance, because it will rarely be used.

Classes also require special treatment in the browser, because an element may have multiple classes, e.g. class="foo bar baz". When parsing the document, the browser needs to split this up so that it can match any of them against CSS selectors.

Are more specific selectors faster to parse?

I don't think we can say that specificity improves parse speed. What it does slightly improve is the render speed. There are other factors that affect your render speed, such as the CSS file size and having to many rules redefining the same class again and again e.g.

A couple of recommendations for improving your renders:

  1. Define your basic rules for those elements you are going to use in general content (paragraphs, lists, bold, italics...). This way you'll overwrite the default browser CSS rules for them.
  2. If there are rules not common for every <li> e.g., that are specific of a module, using the module parent class to define them will avoid the browser to crawl the whole HTML and you won't have to overwrite rules afterwards when you use the same tag for a different design piece.
  3. If there are several levels of child nodes use classes for every of them that needs to be customised instead of adding more levels hanging of the parent class, otherwise you'll end with large chains of hierarchic classes when you need exceptions.
  4. Try creating CSS modules that you can recycle across all your design applying a single class that define that modular element.
  5. Avoid using * on its own if possible. Nowadays is not so much problem as it was 20 years ago, but the more specific the better for speed.
  6. Don't abuse of :before and :after, use them responsibly. This are pseudo-elements that modify the DOM on the fly and sometimes, some browsers do not render them properly.
  7. Try using CSS shorthands as a general rule.
  8. If you use baground patterns, balance image size and repeat frequency. Create a pattern of 40px png or gif instead of using the minimum size of 4px e.g. as the browser will have to render the image 10 times less which worth the small extra file size.
  9. Use sprites for icons an similar elements but not too big. You can make an sprite per color. I also recommend to do it vertically, all in a column. That way you can find icons easily using something like background-position-y: calc(-8 * $module). This method will save you a lot of css rules to define the position and also HTML elements as you won't have to cluster the bg images in both axis (x,y)
  10. If you are using tags always add with and height attributes inline. And if those images are .jpg use a compression of about 60 and saved as progressive jpg.

I think with this basic rules you won't have any render problem in most of the cases.

h1 {
margin: 16px 8px;
font-size: 24px;
color: #999966;
}
p {
margin: 8px 8px 16px;
}
.thumnnail {
float: left;
margin: 0 8px;
}
.content, aside {
display: table-cell;
}
.content {
width: 75%;
}
.content ul {
margin: 8px;
padding: 8px 16px ;
}
.content li {
margin:8px 0;
}
.tabs {
margin: 0;
padding: 0;
background: #ddd;
}
.tab {
list-style: none;
padding: 8px;
}
.tab + .tab {
border-top: solid 2px #fff;
}
<section class="content">
<h1>My title</h1>
<img class="thumnnail" src="https://fakeimg.pl/250x100/" title="my image"/>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
<ul>
<li>Excepteur sint occaecat cupidatat</li>
<li>non proident sunt in culpa</li>
<li>qui officia deserunt mollit anim id est laborum.</li>
</ul>
</section>
<aside>
<ul class="tabs">
<li class="tab">Tab 1</li>
<li class="tab">Tab 2</li>
<li class="tab">Tab 3</li>
</ul>
</aside>


Related Topics



Leave a reply



Submit