是[选择器]> *真的那么慢

时间:2012-06-09 13:29:33

标签: css performance css-selectors

所以我正在构建一组JavaScript(jQuery)小部件,我想确保这些小部件的所有元素都使用box-sizing: border-box(是的,我知道这意味着我只能支持我喜欢的IE版本为8或更高版本。

现在我听说做[selector] > *的速度很慢,但速度有多慢?

我的意思是只有一个小部件,我有这个选择器来确保所有元素都有正确的大小:

.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;
}

但它会更小,更容易写:

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

另外,如果我添加一个元素,我现在必须记住将它添加到巨大的选择器中,与星号一起,我不必担心它。

真的值得花时间单独列出每个可能的元素,因为[selector] > *真的那么慢吗?

更新

最后,我将继续:

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

根据谷歌浏览器,此选择器占总共4毫秒的约14%。其他有点小(约4%),但考虑到它,CSS将是我可能需要担心性能的最后一个地方(我的javascript和服务器端代码将是瓶颈的大部分)。如果我真的需要优化我的CSS chrome profiler就在我需要的时候。

2 个答案:

答案 0 :(得分:6)

如果您真的想在标有该类的容器下所有元素,那么您需要

.jg-grid-wrap *

>运算符将匹配限制为直接子项。

性能影响源于这样一个事实:它意味着在以相关方式更新布局时必须测试每个元素。你可以通过以下方式让它变得更好:

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

等,你真正关心的任何块级元素。 (也就是说,如果您的<span>标签具有“box-sizing”属性,您真的在乎吗?)

Chrome的CSS探查器在查找昂贵的CSS规则方面非常有用。这应该是你在考虑过多之前根据经验进行调查的;现代CSS引擎非常快。

答案 1 :(得分:1)

浏览器在(重新)绘制页面时从右向左评估CSS:

.jg-grid-wrap > *

这将基本匹配页面上的所有元素;然后它检查所有元素的直接祖先并比较该类。

听起来很糟糕,情况可能会更糟:

.jg-grid-wrap *

对于.jg-grid-wrap下的元素,它并不是那么糟糕,但是其他元素会导致浏览器遍历元素树一直到html以找到祖先。

有些逻辑可以在某种程度上进行优化,但仍然可以避免它。因此,诀窍是尽可能使CSS规则中最右边的部分尽可能具体。

所以我的结论是:只留下代码,对于可怜的浏览器而言,对人眼来说最佳的东西可能是灾难性的:)