对于一个前端开发者而言,性能优化是一个老生常谈的问题了,然而优化的方面有很多,比如加载优化、图片优化、渲染优化、打包优化、 js优化、css优化等等。
CSS优化对于浏览器性能的提升不是特别明显,也往往是最被容易忽略的一个优化方向,下面我们来仔细聊聊CSS有关的性能优化,希望对你们平时的工作和面试有所帮助。
高消耗属性在绘制前需要浏览器进行大量计算:
常见的重排元素:
Float在渲染时计算量比较大,尽量减少使用。
动画的基本概念:
一般浏览器的渲染刷新频率是 60 fps,所以在网页当中,帧率如果达到 50-60 fps 的动画将会相当流畅,让人感到舒适。
注:3D 变形会消耗更多的内存和功耗。
使用 translate3d 右移 500px 的动画流畅度要明显优于直接使用 left:
.ball-1 { transition: -webkit-transform .5s ease; -webkit-transform: translate3d(0, 0, 0);}.ball-1.slidein{ -webkit-transform: translate3d(500px, 0, 0);}.ball-2 { transition: left .5s ease; left:0;}.ball-2.slidein { left:500px;}
#header > a {font-weight:blod;}
我们中的大多数人都是从左到右的阅读习惯,会习惯性的设定浏览器也是从左到右的方式进行匹配规则,推测这条规则的开销并不高。
我们会假设浏览器以这样的方式工作:寻找 id 为 header 的元素,然后将样式规则应用到直系子元素中的 a 元素上。我们知道文档中只有一个 id 为 header 的元素,并且它只有几个 a 元素的子节点,所以这个 CSS 选择器应该相当高效。
事实上,却恰恰相反,CSS 选择器是从右到左进行规则匹配。了解这个机制后,例子中看似高效的选择器在实际中的匹配开销是很高的,浏览器必须遍历页面中所有的 a 元素并且确定其父元素的 id 是否为 header 。
如果把例子的子选择器改为后代选择器则会开销更多,在遍历页面中所有 a 元素后还需向其上级遍历直到根节点。
#header a {font-weight:blod;}
理解了CSS选择器从右到左匹配的机制后,明白只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的选择符,或者因为不匹配而退出。我们把最右边选择符称之为关键选择器。
1、避免使用通用选择器
/* Not recommended */.content * {color: red;}
浏览器匹配文档中所有的元素后分别向上逐级匹配 class 为 content 的元素,直到文档的根节点。因此其匹配开销是非常大的,所以应避免使用关键选择器是通配选择器的情况。
2、避免使用标签或 class 选择器限制 id 选择器
/* Not recommended */button#backButton {…}/* Recommended */#newMenuIcon {…}
3、避免使用标签限制 class 选择器
/* Not recommended */treecell.indented {…}/* Recommended */.treecell-indented {…}/* Much to recommended */.hierarchy-deep {…}
4、避免使用多层标签选择器。使用 class 选择器替换,减少css查找
/* Not recommended */treeitem[mailfolder="true"] > treerow > treecell {…}/* Recommended */.treecell-mailfolder {…}
5、避免使用子选择器
/* Not recommended */treehead treerow treecell {…}/* Recommended */treehead > treerow > treecell {…}/* Much to recommended */.treecell-header {…}
6、使用继承
/* Not recommended */#bookmarkMenuItem > .menu-left { list-style-image: url(blah) }/* Recommended */#bookmarkMenuItem { list-style-image: url(blah) }