20

I'm wondering if there is a performance issue using attribute selectors instead of class selectors.

div.test {}
div[test] {}

P.S. : I'm only interested in CSS performance, not JS.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Tot
  • 873
  • 2
  • 13
  • 30

5 Answers5

13

According to this article, class selectors are more efficient than attribute selectors.

Anthony Atkinson
  • 3,101
  • 3
  • 20
  • 22
  • Thanks, interesting article. :) – Tot Mar 09 '14 at 17:45
  • Angular-material team experienced huge performance problems with IE11 recently because of the use of attribute selectors instead of class selectors https://github.com/angular/material/issues/1771. But Chrome and Firefox seem work fine with the attribute selectors. – Alexey Nov 18 '16 at 14:48
  • 13
    this article is 7 years old. Are there any up to date benchmarks? – phil294 Oct 23 '18 at 17:47
  • 1
    But not in any real world amount. An honest answer, after citing that article, would be "class selectors are probably more efficient, but it's not likely to have a real world impact." The question was "is there a performance issue", so the answer is "probably not." – Domarius Feb 17 '21 at 02:47
  • 2
    it's 11 years old now. – Lewis May 04 '22 at 15:02
5

Someone has actually created a real life selector test that showcases selector matching performance.

The table outlines that attribute selectors are approximately 3x slower compared to standard classes.

Relying on attribute selectors also requires more characters to target an element. It's better to define short and concise class names to keep your stylesheet small.

Example:

// 17 Characters (attribute)
[title="example"] {
 ...
}

// 6 Characters (class)
.title {
 ...
}

http://scope.bitbucket.org/tests/selector-matching-performance/

tyau
  • 186
  • 1
  • 2
  • 5
    the comparison of these two selectors is not equal, if you don't specify a value: `[title]`, it is just a 1 character difference. the more important thing to consider is the `data-` prefix, if you find it's worth using to insure that your website functions the same in case a new attribute with the same name was added to the HTML standard in the future, or if you need to use the [HTMLOrForeignElement.dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/dataset) readonly property. though with gzip/compression, most likely there won't be a big difference in size/bytes. – Wis Oct 15 '20 at 03:48
  • 3
    The link in the answer is broken. It is archived in https://web.archive.org/web/20160723023304/http://scope.bitbucket.org/tests/selector-matching-performance/ – Michael T Jan 16 '22 at 09:19
  • Makes sense, but one should always consider whether that speed overweighs other up and downsides. – LuckyLuke Skywalker Feb 09 '23 at 00:12
2

According to this project there is no real performance issue.

This surprised us, since selector performance hasn't been a real concern in our day-to-day work for a while. Front-end performance is a huge deal, of course, but CSS selectors appear to contribute such a minuscule amount to the total page load time that it didn't occur to us that it might be a major concern to many people.

They have benchmarks as well. EDIT: see comment: they have benchmark ideas*, not benchmarks.

https://github.com/amcss/am-benchmarks

PEZO
  • 441
  • 4
  • 14
  • 2
    They don't have benchmarks, they don't have any data yet. It says "WIP". The quote you pasted, when read in context, is basically saying "We haven't noticed a difference." The rest of the article says "Here's how I plan to test it", and the final part of the article says "Haven't run the tests yet. WIP." – Domarius Feb 17 '21 at 02:40
0

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.

Ani
  • 4,473
  • 4
  • 26
  • 31
  • 12
    I was under the impression that the question was not about specificity. – Anthony Atkinson Mar 09 '14 at 20:29
  • 13
    Did you even read the text that you quoted? It groups classes and attributes together, making them both equal, so `div.test` *can't* be more specific than `div[test]`. – BoltClock Mar 26 '14 at 23:26
  • @BoltClock sorry, I meant elements. – Ani Mar 27 '14 at 00:03
  • 1
    That just makes the entire part about specificity irrelevant then, since the question is in fact asking about classes and attributes, not classes and elements. If I were the OP I probably would have accepted Anthony's answer instead even though his is mostly a link and a single statement. – BoltClock Mar 27 '14 at 00:04
  • you are right..But I think OP asked me abt articles and some info to read abt this stuff..hence the link and explanation – Ani Mar 27 '14 at 01:47
  • Indeed, whichever one came last will have the priority, unless it's in a media query – OzzyTheGiant Mar 23 '17 at 14:20
0

Data attributes are slower, but not so much that I would care. Testing it with JS gives me these results:

Test name       Executions per second
.....................................
Class           5017198.0 Ops/sec
ID              3808182.0 Ops/sec
data attribute  3289109.0 Ops/sec

https://measurethat.net/Benchmarks/ShowResult/436379

I'm pretty sure that pure CSS is much faster.

Andrei Surdu
  • 2,281
  • 3
  • 23
  • 32