More CSS Performance Testing (pt 3)

This is now the 3rd part of my current adventures in looking into CSS performance and how it performs in various states across various browsers.

Now before I get into the details and the pretty pictures, a couple of caveats:

  • Try not to focus on the between browser times (although I’ll come back to that later), I’m always wary of testing cross browser and cross OS, all the IE tests were run in Parallels images running on my mac book, although it doesn’t appear of have affected the speeds, it’s just not the same as running IE on a full blown dedicated box. More importantly is the how each browser did in each test and how the times are affected by the various targeting techniques.
  • I’ve not tested in every browser. It took a few hours to do all these tests as I was doing it manually and collected 10 results for every test in every browser. I tried in my current version of IE8, but even the basic “not style” test froze the VM, so I gave up. I also tested a couple of sets in FF2 on XP just to see if I was way off with my results, and they seemed pretty consistent.
  • Despite taking the time to do 10 of each test, I’m also very aware that it’s not a great statistical amount of tests, but there is a clear pattern in most cases, so I’m happy with the conclusions that can be drawn
  • I have no agenda, I’m not setting out to prove X or Y, I am not a fanboy of any particular browser, I work in them all day-in-day out. If pushed I’d say I like Firefox (but only because of all the extension that make my life better), but if those extensions were available in Safari, I wouldn’t look twice at FF.

The Results

CSS Performance Testing, all results in one graph

To explain the tests very quickly:

I’m using a variant of the 20,000 item loop HTML page to test that I used in my last set of CSS tests. Basically, I have two loops one for 20 columns and one for 1000 rows. However last time round there was an interesting question about whether Firefox maybe benefited by “assuming” the structure of a table, this making it’s styling faster. Jake suggested I tried with unrelated tags, so this time round I’m testing 3 levels of nested DIV tags, the lowest one contains a P tag which contains an A tag, that A tag is the thing we’re targeting and styling.

The Control

In this test, we have nothing in the style tag area, so no styling is taking part. We have the identical HTML to all the other tests. The aim is to get a good baseline on how fast the browser can just render the 1.8 MB page from the local file system (all tests are run locally to minimize latency and connection issues, they are also all run using static HTML rather than server generated HTML, again to reduce differences between loads due to server load.

Tag Styling (control +2)

This is really just another control, in this instance we have a single style declaration that sets the background of all the anchor tags to “red”. This is how you would probably approach the styling to get the outcome we have in every test - all anchor tags with a red background.


In every test in our HTML, every anchor tag is given a unique class, in this test the style tag in the head has style declarations for every class in the HTML (20,000 of them), setting each one individually to background red. This is a direct class definition test. Very similar to my control I used in the last set of CSS tests.

Descender Selectors

Again using the same setup as the last set of tests, only now not in a table structure, but the new “div p a” setup. We have 20,000 declarations in the style tag in the head that define each anchor tag not only based on it’s classname, but also that it must be within a P, in a DIV, in a DIV, in a DIV. Again the theory here is that most browser will tackle this issue by reading from left to right, and thus this will be far more effort than just class names.

Child Selectors

There was some misuse of selector type names last time round (by myself included) so I figured I’d add Child Selectors this time just to see how they stack up. These are looking for direct parenting of each of the tag definitions. Again 20,000 of them defined.

How they did

Safari 3
As before with the table HTML, there is significant performance loss between class based definition and descenders and child selectors. (As a side note, with no CSS defined it shows blazing speeds that at first I didn’t believe considering it was running under identical conditions to the FF tests below)

CSS Performance Testing - Safari

Firefox 2 and 3 both have very level graphs, they don’t suffer as great an impact on performance using descender or child selectors. The only caveat here is that the control test scores were consistently awful, so maybe it’s a shallow victory.

CSS Performance Testing - Firefox 2

CSS Performance Testing - Firefox 3

Internet Explorer
IE6 and IE7 had the same amazing control baseline results, but again, like Safari, they suffer considerably when you start using descenders and child selectors, with a drop in performance of over 60% between classname definitions and classname + child selectors.

CSS Performance Testing - IE6

CSS Performance Testing - IE7

My Conclusions

These tests have just further reinforced my results from the last batch using the table html. It doesn’t appear to make a huge difference to the test outcome if it’s a table or unrelated “div p a” tags. FF3 is still winning hands down as the browser that is least affected by the more “complex” selectors. But as noted it’s a shallow victory considering it’s appalling control times. Safari never ceases to amaze at it’s speed doing simple things, and even though it’s huge lead over FF3 is removed once child selectors come into play, the difference is minimal and the test very extreme.

My overall conclusion remains the same, be aware that descender and child selectors can affect performance, but don’t worry about them so much as to not use them.


My next set of tests will be based on some of the more ‘obscure’ selectors, like adjacent and pseudo selectors. I’m also thinking about running some tests that look at what styles are expensive. My last idea is to look at a way to make these tests easier to run. I have a couple of ideas about making the test pages automate and update a central DB using XHR passing the test file title, the result and the user agent string, before reloading the page (thus allowing me to start a test come back 20 minutes later and have 1,000 data points). All of this is dependent on time of course, so who knows.

I’ve uploaded the test files in a ZIP (~900kb) and a CSV output of all the tests in this round.

About this entry