ryanzec
ryanzec

Reputation: 28040

Is [selector] > * really that slow

So I am building a set of JavaScript (jQuery) widgets and something I want to make sure is that all the elements for these widgets are using box-sizing: border-box (and yes, I am aware this means I can only support an IE version of 8 or higher which I am fine with).

Now I have heard that doing a [selector] > * is very slow but just how slow is it?

I mean for just one of the widgets, I have this selector to make sure all elements have the right box-sizing:

.jg-grid-wrap,
.jg-grid-content-outer-wrap,
.jg-grid-colum-actions a,
.jg-grid-content-wrap,
.jg-grid-wrap .hide,
.jg-grid-wrap ul,
.jg-grid-wrap ul li,
.jg-grid-header-wrap,
.jg-grid-header-wrap li,
.jg-grid-header-wrap .sort-indicator,
.jg-grid-row,
.jg-grid-row li,
.jg-grid-footer-wrap,
.jg-grid-footer-wrap .column-selection
.jg-grid-wrap .controls,
.jg-grid-wrap .controls .first-page-link,
.jg-grid-wrap .controls .previous-page-link,
.jg-grid-wrap .controls .next-page-link,
.jg-grid-wrap .controls .last-page-link,
.jg-grid-wrap .controls .column-selection-link,
.jg-grid-wrap .controls .set-page-link,
.jg-grid-wrap .controls .total-page-count,
.jg-grid-wrap .controls .record-counts,
.jg-grid-wrap .controls .record-display-text
{
    box-sizing: border-box;
}

but it would be a lot smaller and easier to just write:

.jg-grid-wrap *
{
    box-sizing: border-box;
}

Also, if I add an element, I now have to remember to add that to the huge selector where with the star one, I don't have to worry about it.

Is it really worth my time to list out every single possible element individually because the [selector] > * is really that slow?

UPDATE

In the end, I am just going to go with:

[class^=jg-] *
{
    box-sizing: border-box;
}

This selector has a ~14% of a total of 4ms based on google chrome. Other has a bit smaller (~4%) however thinking about it, CSS is going to be the last place that I probably need to worry about performance (my javascript and server side code will be the bulk of the bottleneck). If I really need to optimize my CSS chrome profiler is there when I need it.

Upvotes: 4

Views: 553

Answers (2)

Ja͢ck
Ja͢ck

Reputation: 173562

Browsers evaluate CSS from right-to-left when a page is (re)drawn:

.jg-grid-wrap > *

This will basically match ALL elements on the page first; then it checks the direct ancestor of all elements and compares the class.

As bad as that sounds, it could be worse:

.jg-grid-wrap *

For the elements under .jg-grid-wrap it's not so bad, but other elements cause the browser to traverse the element tree all the way up to html to find an ancestor.

Some of this logic can be somewhat optimized, still, it's good to avoid it. So, the trick is to make the right-most part of your CSS rules as specific as possible.

So my conclusion is: just leave the code alone, what seems optimal to the human eye could be disastrous for the poor browser :)

Upvotes: 1

Pointy
Pointy

Reputation: 413709

If you really want all elements under the container marked with that class, you'd want

.jg-grid-wrap *

The > operator limits the match to direct children.

The performance impact stems from the fact that it means every element has to be tested when the layout is updated in relevant ways. You could make it a little better with:

.jg-grid-wrap div, .jg-grid-wrap form, .jg-grid-wrap ul

etc, with whatever block-level elements you really care about. (That is, do you really care if your <span> tags have the "box-sizing" property?)

Chrome's CSS profiler can be pretty helpful in finding expensive CSS rules. This should be something you investigate empirically before worrying about it too much; modern CSS engines are pretty fast.

Upvotes: 6

Related Questions