我在一个相当复杂的Web应用程序中对一些SASS选择器进行了一些小改动,并且看到了显着的性能下降。使用Chrome的时间轴功能对页面进行概要分析时,"重新计算样式" (在我假设的DOM操作之后回流页面)从大约1ms变为大约100ms,并且受影响的元素计数这些样式重新计算从大约10变为大约1500.
是什么让这个选择器变得如此邪恶?在将来,我应该警惕什么才能不再犯同样的错误?
原创CSS(快速):
.button-group .button:not(:last-of-type) {
margin-right: -1px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.button-group .button:not(:first-of-type) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
修改CSS(非常慢):
.button-group > :not(:first-of-type) .button, .button-group > :not(:first-of-type).button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.button-group > :not(:last-of-type) .button, .button-group > :not(:last-of-type).button {
margin-right: -1px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
答案 0 :(得分:0)
为了打破这一点,我将忽略.button-group
,因为两者都是一样的,不会影响任何事情。
在第一个示例中,您选择每个button
类。浏览器针对搜索类进行了优化,因此通常非常快。然后使用not(:last-of-type)
修饰符,这个修饰符较慢,但无关紧要,因为池已经仅限于button
类。
在第二个示例中,首先搜索:not(:first-of-type)
,这会对.button-group
的每个孩子执行昂贵的操作。虽然使用直接子操作符(>
)将有助于限制该池,但它可能仍然是比第一个示例更多的元素。我不太确定你要用.button, &.button
做什么,但无论哪种方式,操作都不是很昂贵,因为你只是按类选择而且你已经把游戏池限制了很多。
因此,一般而言,您希望从成本最低的操作转到成本最高的操作,以便在尽可能少的元素上进行密集计算。
旁注,我想你在第二个例子中.button
之后错过了一个逗号。
编辑:只想指出两段代码编译的区别。
首先:
.button-group .button:not(:last-of-type)
第二
.button-group > :not(:first-of-type) .button,
.button-group > :not(:first-of-type).button {
正如你所看到的,第二种情况还有很多。仅此一点可能是它变慢的原因,尽管我现在正在检查以确保not
的排序有影响。