Are CSS selectors a big performance hit? - css

I have a web application with bunch of HTML code. There are some style-attributes that I can't get rid of, but I was wondering if it's worth the cleanness to get rid of class-names and use CSS selectors instead. Do CSS selectors perform slowly?
I'm talking about replacing class-name selectors such as .example with more complex selectors like #example div > div:nth-child(3) > p

Take a look at this article to see a graph on this. I don't know how exact this benchmark is, but it seems child selectors are indeed slower, but you're not going to find any visible gains by avoiding child selectors.. this is a micro optimization that has "diminishing returns" written all over it.

The performance hit is tiny.

Here you can find an interesting blog post on the argument with examples and tests of CSS selectors performances on most common browsers:
http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
This is the conclusion of the author:
Based on these tests I have the
following hypothesis: For most web
sites, the possible performance gains
from optimizing CSS selectors will be
small, and are not worth the costs.
There are some types of CSS rules and
interactions with JavaScript that can
make a page noticeably slower. This is
where the focus should be.

The browser matches from right to left, and any non-specific tags will cause more of a performance hit.*
1–Slower:
.foo p
2–Faster
.foo p.bar
What happens is in the first example, the browser matches ALL paragraphs, then narrows it down to those whose ancestor has the foo class.
In the second example, the browser matches all elements that have the bar class, then matches the subset that are paragraphs, then the subset whose ancestor has the foo class.
One would generally expect the initial set of the second example to be smaller than that of the first example.
*Bear in mind that the hit will really only become apparent with poorly-crafted CSS on pages that are very large (megs) and/or have many, many elements (e.g., hundreds of spans or divs). Small pages with only a few number of elements will not see a real—if any—performance hit, even with poorly-written CSS.

Related

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

I have been reading a lot of CSS performance articles, such as;
Efficiently Rendering CSS
Writing efficient CSS selectors
Writing efficient CSS
I get why selectors like this are bad
#social a {
}
As the browser will read a first, then is forced to loop through all the <a> tags in the page.
But why is a selector such as a[title="home"] slower than using a class?
I assume that the browser creates some sort of an index to be able to figure out what elements have a certain class (Correct?).
But shouldn't browsers also have indexed up what elements have a certain attribute? (such as title)?
My question is; why is the CSS / element look up way slower when using selectors such as a[title="home"] compared to using a class? What or how does the browser act in order that the result is so much slower?
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.
Benchmark
Conclusions
In most cases 'attribute selector with unknown attribute, e.g. [a="b"]' and 'attribute selector with known attribute, e.g. [title="a"]' showed up in the '3 Worst' category. It's safe to say you should avoid those selectors.

Is having a long CSS selector bad?

Is a selector like
.a, .b, .c, .d, .e, .f, .g, .h, ......... , .zzzzz {font-size:16px}
bad for performance? If yes how and if no why?
I Googled and read a lot of posts including the ones by Mozilla and couldn't find any mention of having a large number of class names as a selector being bad.
No, there is no performance problem here.
What is bad is a long selector involving many checks but your selector is in fact a sequence of selectors, equivalent to
.a {font-size:16px}
.b {font-size:16px}
...
Selectors with just a class are among the most efficient ones.
There's no real problem, even if you probably should have less classes in order to manage your code more easily.
This is the valid syntax for assigning a common properties to multiple classes at a time. there is no down side effect.
Saving a single bite is good. Yup as #dystroy said it's doesn't impact that much on your page performance but it's not a good coding particle & also it's hard to manage your code.
Write like this:
body{font-size:16px}
You didn't choose a large selector, you just assigned many selectors to your stylesheet. A large selector would be for example:
header nav ul li a
As the browser uses selectors from right to left the key-selector (the last selector in line, in this example the anchor-element a) is too general. When beginning to render the style the browser begins to grab for all elements according to the key-selector, what would probably mean, that it got much more elements, as effectively needed. In this example it would be much better, if navigation items get unique classes, so the stylesheet must only be applied to following selector:
.primary-link
So, it's import the right key-selector for your styles, to reduce the rendering time to a minimum.
If you want to read something interesting about CSS selectors and performance I can recommend that page: http://learn.shayhowe.com/advanced-html-css/performance-organization

Nested selectors performance impact and LESS

I have been reading for the past 1.5 hours about this and still couldn't find a concise and decisive answer.
As far as I understood browsers parse CSS selectors from right to left.
That means a long CSS selector such as this:
.card .container .businesscard .pinfo li.pinfo-box span:first-child
is one of the least efficient lines of code to ever appear here in SO.
First of all, am I right on this one?
Secondly, I am designing a rich UI using LESS, which ultimately produces this kind of mammoth selectors out of the nested designs I am coding.
What can be done to avoid this kind of selectors? Rely on classes and IDs alone? But then again what is the purpose of using LESS if you can't write nested CSS?
Your input is appreciated.
That is correct. Browsers evaluate selectors from right to left. It will try to find a span inside a li.pinfo-box and so on.
One rule of thumb to folllow when writing LESS is: do not nest more than 3-4 levels.
This will prevent your selectors from growing to big, while you will still be able to benefit from the nesting feature in LESS.
A good example of "useless" nesting is when styling lists. Sometimes I write the selectors like this:
#wrapper .blog-post ul, #wrapper .blog-post ul li
Is it really necessary to specify that the li must be inside a ul? It will probably be enough writing:
#wrapper .blog-post li
All of this is good to know. BUT: This is not the first thing to dive into when trying to optimize your sites performance. Spend some time lower the number of request or something else instead.
Selector parsing and matching is unlikely to be a big factor unless you have pretty unusual content. I would suggest using whatever is maintainable and gets the job done, up until the point where testing shows a performance issue. Then I'd get out a profiler (on OSX I'd use Instruments, but there should be a decent one available for most platforms) and attach it to the browser; if selector matching shows up high on the profile, then look into replacing slow selectors with faster ones (id selectors are definitely a good bet).

CSS selector performance

I know the performance difference is miniscule, but which is a faster CSS selector?
div.class{ }
or
.class{ }
CSS Selectors are parsed right to left, and then displayed, and the full rule is always parsed. So that would lead me to believe that .class is slightly quicker than div.class. That said, there's also the time taken to render the page, so it may depend on how many elements have that class and how complex the rule is.
Now with all of that said, check out the first answer here: https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
The performance difference is so minuscule (if detectable at all) that it's not worth even thinking about.
Use div.class if you need some styles to only apply to div elements with that class, use .class otherwise. Base your decision on what your styling needs are, not some infinitesimal performance benefit.
Note: There are some selectors that really are (relatively) slow and might be worth changing, things like .class > *. But, even for selectors with really bad performance, and even if you're at a reasonable stage in your project to start thinking about optimizing things, there are exactly a million things you should worry about first before you get to CSS selector optimization.
I think it may depend on browser, you can check selectors here:
http://jsperf.com/jquery-performance-bn/3
In my browser (Opera 11.62) div.class was a lot faster.
.class {} selector is faster than div.class {} because in the first case browser only checks that the element has specified class, whereas in the second case it additionally has to check the element is actually a div.
I don't even remember asking this question at this point, but here's the jist:
The performance difference is minute, EXCEPT when using a JS library like jQuery. To evaluate $('.class'), jQuery checks all elements in the DOM. To evaluate $('div.class'), it only checks divs. So depending on the size of the DOM and the elements in it, the performance difference can be pretty significant.
So really, the pure CSS performance is almost exactly the same, but performance when run though a Javascript selector engine can be noticeably different. I think that is what I was aiming for when I asked this. Thanks to everyone for your comments, you all get upvotes :)

Is there more to optimizing CSS than minimizing character count?

I've been reading a lot about jQuery optimization and how you can alter your selectors to cut down on the amount of DOM traversal, but I haven't heard much about CSS optimization outside of the usual minifying process. Is there any way to optimize your CSS loading/processing outside of just reducing character count and server requests?
You can definitely optimise your selectors for performance. One key point is that CSS parsers read selectors right to left, whereas javascript selector engines (like jQuery etc) read them left to right. Basically though, the general principles are the same - you want each piece of the selector to match as few elements as possible, to cut down on the DOM nodes that have to be searched in order to determine a match.
That means, just like javascript, selecting a single, bare id in CSS is the fastest way you can get to an element. Selecting everything *, or selecting based on attributes ([href*=foo]) are among the slowest.
The reading order creates a difference between optimising jQuery selectors and CSS selectors: you don't gain speed by starting with an ID. For example, if you write:
#mainContent ul li
In jQuery, you are starting by finding the element with the ID mainContent, which is very fast, then digging through it's children.
In CSS, though, you are starting with all li elements, then looking to see if they have a ul ancestor, then checking if they're inside #mainContent. Much slower.
Possible gains in speed
You should also know, however, that CSS parsing is much, much faster than javascript DOM traversal - so even when you do have lots of complex, 'slow' selectors, you're unlikely to see a huge gain in performance by optimising them. Here's a good article on the increases in performance: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/ - the author points out that he could increase rendering time by about 20ms by creating a huge, complex stylesheet and document (6000 DOM elements, and 2000 CSS rules). For a more 'normal' page, your gains would therefore likely be less than 20ms - probably not worth the effort.
My view is that it's good to keep selector performance in mind while you're writing CSS, but don't let it make your stylesheets less readable or maintainable. In the majority of cases, it's not worth optimising an existing stylesheet, unless you can identify some selector that is really unnecessarily slow.
Here is some more good reading on the subject:
http://css-tricks.com/6386-efficiently-rendering-css/
http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
After reading some of the resources people posted in response to this question I stumbled across this (eleven year old) gem, which is still just as helpful as it was when it was written:
https://developer.mozilla.org/en/Writing_Efficient_CSS
The other big takeaway I found in my research is that you shouldn't sacrifice clean (maintainable) code or semantic best practices for CSS efficiency because the gain is so small. Still, I like my code to be clean AND efficient if at all possible, and the answers here have give me a lot to think about when writing CSS.
Yes, you can make your CSS better in terms of selector matching efficiency. By making your selectors as specific as possible, you reduce the effort needed by the HTML renderer to search the DOM for matching elements.
For example, in the cases where you know that all the spans you want to style will be direct children of the div element within your element with id #thing. it would be faster to do:
#thing > div > span.my-class
than
#thing span.my-class
because that restricts the elements that the selector has to search to find a match.
Merging stylesheets if you have multiple (remember to keep the order right)
You can also host your static content on a different server as your application (a http server optimized for serving static content), like Lighttpd

Resources