如何在性能上更好地编写CSS
在今天的帖子中,我们将考虑可以在CSS中进行选择以提高站点性能的代码。 但是,在深入探讨这些选择之前,我们首先简要地仔细研究一下网页渲染工作流程 ,以便专注于 可通过CSS解决的问题(性能方面)区域。
这是在创建DOM树之后浏览器执行的操作的大致流程:
- 重新计算样式(并渲染树的创建)。 浏览器计算要应用于DOM树中元素的样式。 稍后创建渲染树,同时从DOM树中丢弃不渲染的节点(元素,带有
display:none
元素)和那些节点(元素)(伪元素)。 - 布局(又名回流)。 浏览器使用之前计算的样式,计算页面上每个元素的位置和几何形状。
- 重涂。 布局映射后,像素将绘制到屏幕上。
- 复合层。 在重新粉刷时,可以自动在不同的图层上进行粉刷; 然后将这些层最终合并在一起。
现在,让我们继续进行操作的前三个阶段,以编写性能更好CSS代码。
1.减少样式计算
然后,它遍历那些选择器中的所有样式规则,并确定哪些样式规则将实际应用于元素。
为此,浏览器首先在CSS中找出指向DOM树中给定元素节点的所有选择器。
如前所述,在“重新计算样式”阶段,浏览器计算要应用于元素的样式。
这减少了计算时间。
为避免进行昂贵的样式计算,请减少复杂且嵌套较深的选择器 ,以使浏览器更容易确定选择器所指的是哪个元素。
其他使用方式包括减少样式规则的数量 (在可能的情况下), 删除未使用CSS并避免冗余和覆盖 ,以使浏览器在样式计算期间不必一次又一次地使用相同的样式。
2.减少回流
元素中的重排或布局更改是非常“昂贵”的过程,当经历了布局更改的元素有大量子级时,这可能会带来更大的问题(因为重排在层次结构中向下层叠 )。
重排是由元素的布局更改触发的,例如更改几何属性(例如高度或字体大小,向元素添加或删除类,更改窗口大小,**:hover
,通过JavaScript更改DOM等)。
就像在样式计算中一样,要减少重排,请避免使用复杂的选择器和较深的DOM树 (同样,这是为了防止重排过多的重排)。
这样,布局更改不会触发(几乎)任何其他重排。
如果必须在页面中更改组件的布局样式,请以组成该组件的元素层次结构中最低的元素的样式为目标 。
如果您要对经过布局更改的元素进行动画处理, 请绝对定位它 , 将其从页面流中 移出 ,因为绝对位置的元素中的Reflow不会影响页面上其余的元素。
- 进行布局更改时,目标元素位于DOM树中较低的位置
- 选择绝对定位的元素以更改布局的动画
- 尽可能避免对布局属性设置动画
3.减少重涂
重绘可以通过重排,页面滚动,颜色,可见性和不透明度等属性更改来触发。
重绘是指屏幕上像素的绘制,就像重排一样,这是一个昂贵的过程。
为了避免频繁且大量的重绘,请少使用导致阴影等昂贵的重绘的属性 。
在硬件加速中,GPU将承担在图层中执行动画更改的任务,从而在加速过程的同时节省了CPU的额外工作。
如果您要对可以直接或间接触发Repaint的元素进行动画处理,则如果该元素位于其自己的图层中,从而防止其绘画过程影响页面的其余部分并触发硬件加速,则将具有很大的优势。
因此,最好将这些属性用于动画。
在某些浏览器中, opacity
(值小于1
)和transform
(值none
除外)会自动提升到新层,并且硬件加速会应用于动画和过渡。
为了将元素强制提升到新层并进行动画的硬件加速 ,涉及了两种技术:
- 添加
transform: translate3d(0, 0, 0);
元素,从而诱骗浏览器触发动画和过渡的硬件加速。 - 将
will-change
属性添加到元素,这会将将来可能在元素中更改的属性通知浏览器。 注意 :Sara Soueidan在Dev.Opera网站上对此有深入且超级有用的文章 。
总结一下:
- 避免使用昂贵的样式导致重涂
- 寻求层级提升和硬件加速,以获取大量动画和过渡效果。
做记录
由于此代码减少,编写了更好的选择器并删除了未使用CSS, 文件大小将自动减小 。
我们已经提到,减少样式规则(和DOM元素)可以显着提高性能,因为浏览器在计算样式的过程中需要减少多少工作 。
(1)到目前为止,我们还没有涉及CSS文件大小的减小。
而是将一个类添加到包含新样式的元素(使用JavaScript)来进行这些更改-这样可以避免不必要的重排。
(2)也建议不要对JavaScript中的元素样式进行过多的相应更改 。
在此处阅读有关如何影响性能的更多信息。
(3)您还将要避免由于使用JavaScript访问和修改元素的Layout属性而引起的布局限制 (强制同步重排)。