Monday, May 12th, 2008
CSS Child Selector Performance
Are child selectors slower than more simple brethren? This is a question that Jon Sykes sought out data for after he read the work of Jim Barraud.
His conclusion?
The skinny is that child selectors are a major performance issue.
This seemed to make sense, but to me I needed some sort of proof rather than just being told it’s that way by someone, so over the last two days I’ve tried two approaches to see if I can replicate the issue.
The first one was rather a half-assed idea that afterwards seems fundamentally flawed as a benchmark.
So I took a new approach which does seem to return some valid and rather interesting findings, particularly regarding Safari and Firefox 3 and how they react to child selectors and performance.
The tests show that there is slow down using child selectors over direct class name declarations in IE6, IE7 and Safari 3. Safari 3 being the most impacted by child selectors. Firefox 2 has some impact, and Firefox 3 doesn’t seem to be impacted at all.
That said, this is a very extreme test, it is not often you’d have 20,000 class definitions in a single page or that all of them would use 4 levels of child selector.













.className may not render correctly compared to table tr td.className if you have 2 different rule sets. Since the second is more specific, it will take precedence.
That’s right JonT. But I think the point was that “If that dependency is NOT your case…” then simplifying your selector use could be *slightly* beneficial. I have to wonder if the actual page rendering engine of a browser goes through the same issues. If so I have to wonder if simplifying CSS selector use in static HTML pages might help rendering speed. A little. Maybe.
I agree with JonT. “.className” isn’t specific enough and could increase developer ramp-up time if you were to throw a developer on a project he’s never been on before. I’ve seen a lot of stylesheets have 4-6 levels because of shadows + rounded corner modules…Yeah, it can get ugly, but sometimes the client needs crazy rounded corners, gradients, and shadows–and they’re willing to pay for it!
In his test for 20,000 dom nodes he says that it is very extreme–That’s great! I always ask myself, “How far can we push a web application to its limits in terms of user experience, functionality, and performance?”
Kudos to Jon for a good find.
hmm I use the left “style” all day to correctly identify the element I meant. Hmm the opposit would be to create millions of classnames instead. :-/
Great information! Thanks for sharing it.
I always felt that the more specific the selector rule, the worse the performance. It’s usually better to have a generic selector rule rather than a specific one.
Of course, that’s all anecdotal.
Do note that this if for CSS rendering speeds only. When using CSS Selectors inside a javascript library, something like
td.classNameis far faster than.className.I’m a little flabbergasted.
I’ve always thought that over specifying meant that you CSS node parser did not waste time on nodes that could not fill the criteria and therefor would be faster…
I’d love to see techniques for speeding up stylesheets on large and complicated CSS structures.
It seems to me the only thing CSS optimisers know how to do is get rid of the added specifications… which to me was just aimed at minimizing file weight… but getting rid of something much more precious which was actual knowledge of where the style are to be applied (and where we do not need to look for them.)
Looks like a whole lot of wrong assumptions
I guess my preconceptions would only work if you have direct descendant selectors…
Jerome, I respectfully disagree with your logic. I would posit that in the case of .className the browser doesn’t waste time on anything without that class name. In the case of the specific “table tr td.className” selector the browser would find all the tables, then all the rows within the tables, then the cells and then go through all the elements in the cells to find .className
Of course I could be wrong :)
These numbers are already showing me I’m wrong. :)
I’m realizing now that simple child selectors are not precise at all…
My intention was really to tell the parser… “you don’t need to go look at this section of the page, these are not the nodes you’re looking for” ;) … but I was fooling my self… it doesn’t do that at all, nor could it… this would only have a chance of working if you used the “child” selector and not the “descendant” selector… so I wonder what “table>tr>td.classname” as opposed to “table tr td.classname” would do (and then maybe “body>table>tr>td.classname”)… especially in a large document where there’s only 1 table. Only IE 5.5 and 6 does not support “child selectors”…
(The article is misleading as it seems to use the term “child selectors” where it should use “descendant selectors”)
Sorry I meant to say”I’m realizing now that simple DESCENDANT selectors are not precise at all…”
In my case it is mostly more like this:
“table.foo tr td” and the other way would be “td.foo”, because so I can style more tables independent.
No IE8?
I’ve just gone through and done a series of new css performance tests, with a greater number of data points, better controls, a slight tweak to the HTML I’m using for the tests (based on some feedback) and the addition of actual child selector tests as well as the original descender tests.
@seancallan, I didn’t find IE8 stable enough to run any of these tests, it might be the size of the files combined with me running IE8 on an XP VM on OSX so it’s running out of memory, but the browser would just freeze running just the basic control test.