CSS性能优化

1,400 阅读4分钟

坊间传闻CSS优化空间小的说法,对性能影响不大,当然对于这种说法,作为一个进击的前端er是持怀疑态度的。毕竟前端技术水太深,还是在自己能力范围内踏踏实实一步一脚印滴把事情做到极致才是对这份赖以生存的职业最大的尊重。所以本着实事求是的原则,既然有更好的实现方式,又为什么不去follow呢?

CSS选择器性能损耗主要源于从DOM Tree —> Render Tree —> Painting 的过程,也即 浏览器匹配选择器和dom文档结构所消耗的时间,首先我们需要明确的是浏览器对于CSS选择器采用从右向左进行规则匹配,所以在实际操作中,很多best practice可以帮助浏览器进行快速匹配。那么实际应用中主要从以下几方面来对CSS使用进行优化:

  • 加载
    1. 减小文件体积,—> 代码压缩。
    2. 减少加载阻塞,—> 减少使用@import (浏览器不能并行下载样式,使用import会导致页面增加额外的往返开销),可通过使用link标签(可以并行下载CSS文件)替代@import,需要注意的是一个页面中的CSS文件不宜过多,否则应简化和合并外部CSS文件以节省请求时间,从而提升页面加载速度。

  • 选择器性能

Google 资深web开发工程师 Steve Souders 对 CSS 选择器的执行效率从高到低做了一个排序:

1.id选择器
2.类选择器
3.标签选择器
4.相邻选择器
5.子选择器
6.后代选择器
7.通配符选择器
8.属性选择器
9.伪类选择器

在了解了浏览器的匹配原则和不同选择器的执行效率后,那么当嵌套使用选择器时,嵌套深度和最右侧的选择器的执行效率则很关键,下面可以结合实际应用来介绍一些Best Practice:

  1. 优先使用class选择器,可替代如多层标签选择器规则,增加浏览器匹配效率。
  2. 谨慎使用id选择器,id选择器在页面中是唯一的,不利于团队协作和代码维护。
  3. 利用选择器的继承性,避免过分限制选择器导致浏览器工作效率降低。
  4. 避免CSS正则表达式规则。

  • 渲染性能

    这里写图片描述

上图为浏览器解析DOM Tree 到 Render Tree 再到 Painting 的过程。所以在浏览器渲染过程中可以进行提高的部分包括:

  1. 减少使用高开销的CSS属性(即绘制前需要浏览器进行大量计算的属性)如box-shadow, border-radius, transparency, transforms and css filters等。
  2. 减少重排(Reflow),重排意味着元素位置发生改变,对于交互性较强的web引用来说,重排是在所难免的,但仍然可以从以下几方面进行优化:

    • 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className。
    • DOM 离线后修改,如先把 DOM元素 给 display:none (有一次 Reflow),然后修改100次,最后再把它显示出来。
    • 尽可能不要修改影响范围较大的 DOM元素。
    • 为动画元素使用绝对定位 absolute /fixed。
    • 不使用 table 布局,可能很小的一个小改动会造成整个 table 的重排。
  3. 减少重绘(Repaint),重绘意味着元素位置不变,浏览器仅仅根据新的样式重绘该元素(如border-color,background-color,visibility等)。

  4. 优化动画,启用GPU硬件加速。
  5. GPU加速可以不仅应用于3D,而且也可以应用于2D,通常可以应用于Canvas2D,布局合成(Layout Compositing), CSS3转换(transitions),CSS3 3D变换(transforms),WebGL和视频(video)。

以上为常见CSS性能优化的一些方面,实际开发中应综合业务需要进行组合使用,毕竟功能与性能之间总是需要一些权衡的,所以一切事情都是相对的,应以辩证的角度对待。