Testing CSS Performance (pt 2)

So after yesterdays idea of measuring how long it would take for a node to “turn red”. I came to the decision that that probably isn’t the best way to measure overall techniques and impact of using large amounts of descendant selectors in your CSS.

My new approach for today is sheer volume.

Using my test page from yesterday that has a 20 column by 1000 row table, with each cell having it’s own unique id and class.

I have now extended it to generate CSS in the head 1 style declaration for each cell, same as before the background is just red. This means that in the head of my test page I have 20,000 style declarations.

I am then able to make two versions of this file, one using the format:

  1.  
  2. .tdxx{
  3.   background: red;
  4. }
  5.  

and one where they are all:

  1.  
  2. table tr td.tdxx{
  3.   background: red;
  4. }
  5.  

All of the content is generated with PHP loops, so I ran the two test pages through my local apache and saved the generated HTML. I saved the two files to my desktop and then opened them in various browser.

Once open and loaded and refreshed them 3 times and recorded the results for IE6, IE7, Firefox 2 (osx), Firefox 3 (osx), Safari 3 and Opera.

I went through and ran it in all the above browsers and then collated the data. In case you’re curious, Opera 9 (osx) couldn’t even show the page, and would choke and crash, so I don’t have any data on them.

The results were rather interesting:

Browser Child Selectors Average Direct Class Name Average
FF2 3200 3186 3704 3363 3054 2497 2914 2822
FF3 2612 2760 2415 2596 2437 2589 2355 2460
IE6 3515 3685 3645 3615 3025 2494 2734 2751
IE7 3765 3515 3545 3608 2364 2433 2263 2353
Safari3 4451 4604 4530 4528 2874 2673 2760 2769

Which looks like:

The green bar is the average time that the page took to render when you use 20,000 direct class name css declarations, the blue is the same but using lots of descendant selectors with the class name (see the example above).

You can clearly see the trend that single class name declarations are faster. But what really amazed me was how much that seems to impact Safari and to a lesser degree IE7 more than Firefox. Firefox 3 running on a mac had probably a negligible difference (based on this being an average of 3 refreshes rather than hundreds of them).

I was also surprised that the impact on Safari is the reverse of what I expected. I expected the slow one to be as fast as the fast one on Firefox and the fast way to be an improvement. The reverse seems to be the case. Descendent selectors are a major slow down to the Safari browser, rather than single class declarations being a performance gain.

That is surprising to me, considering all of these tests were run on OSX (the IE tests were run in a memory starved Parallels image). We have to be careful doing browser to browser comparison, as the tests weren’t all conducted at the same time under the same circumstances.

Conclusion

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 descendant 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.

That said it is something to be aware of and keep an eye on, and if you’re looking at ways to optimize css reduction of descendent selector usage might help.

If you’re interested in running the test, I have the two files as a ZIP for download (they upzip to 2+ megabyte HTML files, so I zipped them). Just run them locally and you can see the results at the top of the page.


About this entry