原文地址:web.dev/reduce-the-…
JavaScript通常是视觉变化的触发因素。有时是直接通过样式操作,有时是计算会导致视觉变化,比如搜索或排序一些数据。不合时宜或长时间运行的JavaScript可能是导致性能问题的常见原因,您应该尽可能将其影响降至最低。
通过添加和删除元素、更改属性、类或动画来更改DOM,都会导致浏览器重新计算元素样式,在许多情况下,还会对页面或其部分进行布局(或回流)。这一过程称为样式计算(computed style calculation)。
计算风格的第一部分是创建一组匹配的选择器,这本质上是浏览器确定哪些类、伪选择器和ID应用于任何给定的元素。
该过程的第二部分涉及从匹配选择器中获取所有样式规则,并找出元素的最终样式。在Blink(Chrome和Opera的渲染引擎)中,这些过程至少在今天的成本上大致相当:
摘要 #
- 降低选择器的复杂性;使用以类为中心的方法论,如BEM。
- 减少必须对其进行样式计算的元素数量。
减少选择器复杂度(Reduce the complexity of your selectors) #
在一个简单的案例中你可能会使用如下的选择器进行class查找
.title {
/* styles */
}
但是,随着任何项目的发展,它可能会导致更复杂的CSS,因此您最终可能会得到如下选择器:
.box:nth-last-child(-n+1) .title {
/* styles */
}
为了知道样式需要应用,浏览器必须有效地问“这是一个具有标题类的元素吗?它的父元素恰好是具有box类的减去第n个子元素加1个元素?”根据使用的选择器和有问题的浏览器,弄清楚这一点可能需要很多时间。选择器的预期行为可以改为如下选择器:
.final-box-title {
/* styles */
}
你可以使用特定类对最后一个元素进行标识,对于浏览器来说效率便可以有很大提升。例如,在以前的版本中,为了知道元素是其类型中的最后一个,浏览器必须首先知道所有其他元素的所有信息,以及在它之后是否有任何元素将是第n个最后一个子元素,这可能比简单地将选择器与元素匹配要昂贵得多。
(减少赋予样式的元素数量)Reduce the number of elements being styled
另一个性能考虑因素是元素更改时需要执行的工作量,这通常是许多样式更新的更重要因素。
一般来说,计算计算的元素样式的最坏情况成本是元素数量乘以选择器计数,因为每个元素至少需要对照每个样式检查一次,以查看它是否匹配。
样式计算通常可以直接针对少数元素,而不是整个页面。在现代浏览器中,这往往不是什么问题,因为浏览器不一定需要检查所有可能受到更改影响的元素。另一方面,较旧的浏览器不一定针对此类任务进行了优化。在可能的情况下,应该减少无效元素的数量。
使用BEM(Use Block, Element, Modifier) #
BEM (Block, Element, Modifier)
BEM的优势
- 实现css的namespace(虽然现在已经有了scope之类的功能)
- 减少选择器层级与复杂度:
例如不使用BEM(sass):
.item {
/*selector*/
.active { /*selector*/ }
}
使用BEM:
.item {
/*selector*/
}
.item--active {
/*selector*/
}
甚至可以
.item {
/*selector*/
&--active {
/*selector*/
}
}
sass编译后,也可以得到例2中的结果
- 便于样式覆盖。如果是嵌套的形式,会导致选择器权重增大,不利于其他选择器进行样式重写(尤其是在组件库中)。使用BEM则没有这个问题。