views:

834

answers:

4
+13  Q: 

Speed of CSS

This is just a question to help me understand CSS rendering better.

Lets say we have a million lines of this.

<div class="first">
    <div class="second">
        <span class="third">Hello World</span>
    </div>
</div>

Which would be the fastest way to change the font of Hello World to red?

.third { color: red; }
div.third { color: red; }
div.second div.third { color: red; }
div.first div.second div.third { color: red; }

Also, what if there was at tag in the middle that had a unique id of "foo". Which one of the CSS methods above would be the fastest.

I know why these methods are used etc, im just trying to grasp better the rendering technique of the browsers and i have no idea how to make a test that times it.

UPDATE: Nice answer Gumbo. From the looks of it then it would be quicker in a regular site to do the full definition of a tag. Since it finds the parents and narrows the search for every parent found.

That could be bad in the sense you'd have a pretty large CSS file though.

+6  A: 

You have to understand how the selectors are being processed:

  • .third: get every element and check for a class name third,
  • div.third: get every DIV element and check for a class name third,
  • div.second div.third: get every DIV element, check for a class name second, run through these and find every decendant DIV element and check for a class name third,
  • div.first div.second div.third: get every DIV element, check for a class name first, run through these and find every decendant DIV element, check for a class name second, run through these and finally check for a class name third.


Edit   I have to admit, that the procedure above would be the naive approach and is not generally efficient. In fact, there are implementations that go from bottom to top instead from top to bottom:

  • div.first div.second div.third: get every DIV element, check for a class name third, get the first DIV ancestor that has a class name second, get the first DIV ancestor that has a class name first.
Gumbo
there are even engines which trawl through the dom rather than the CSS - does this element match this selector? No? How about this one? All manner of shortcut logic exists too.
annakata
Google's Page Speed has some very useful info: http://code.google.com/speed/page-speed/docs/rendering.html - in short, they say using just classes and IDs on their own, with no qualifying tags, is fastest.
DisgruntledGoat
A: 

I would say this depends on the browser. Nothing beats an experiment, in this case a simple JavaScript would probably do.

Update: I meant to do something like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>CSS Speed Test</title>
    <style type="text/css">
    .first { color: red; }
    </style>
    <script type="text/javascript">
    window.onload = function()
    {
        var container = document.getElementById("container");
        var totalTime = 0;
        var passes = 100;
        for (var p=1; p<=passes; p++)
        {
            var startTime = new Date();
            for (var i=0; i<1000; i++)
            {
                var outerDiv = document.createElement("div");
                var innerDiv = document.createElement("div");
                var span = document.createElement("span");
                outerDiv.className = "first";
                innerDiv.className = "second";
                span.appendChild(document.createTextNode("Hello, world!"));
                outerDiv.appendChild(innerDiv);
                innerDiv.appendChild(span);
                container.appendChild(outerDiv);
            }                       
            var endTime = new Date();
            totalTime += (endTime - startTime);
        }                           
        alert("Average time: " + totalTime/passes);
    }
    </script>
</head>
<body>
    <div id="container"></div>
</body>
</html>

…but the time differences caused by different selectors appear to be too small to measure, just as annakata said.

zoul
Oh, of course I meant to *time* the various selectors using JavaScript.
zoul
oic - makes sense now :)
annakata
+10  A: 

Two things to remember:

  • This is going to depend on the CSS parser /rendering engine: i.e. it varies from browser to browser.

  • CSS is really, really, really fast anyway, even at it's slowest the human watching shouldn't notice

In general the simplest things are the fastest (as Gumbo nicely illustrates), but because we're already in such a fast environment don't think that you should sacrifice clarity and appropriate scoping (low specificity is like making everything public sort of). Just avoid * wherever you can :)

annakata
+3  A: 

According to the Mozilla Developer Center, the most efficient selector for this case would be simply .third

In fact, they state there, explicitly, "Don't qualify Class Rules with tag names". In general, for greatest efficiency, use the simplest selector that matches. That's why .third beats span.third beats .second span.third, etc.

I can't tell what Gumbo's conclusion is meant to be, but Ólafur appears to be drawing the conclusion from it that using more stuff in the selector makes the CSS parsing more efficient, when, in fact, it's just the opposite (assuming other CSS parsing engines work similarly to Mozilla's.)

Andrew Hedges
Nice answer there.
Ólafur Waage