CSS性能优化【学习总结于记录】

提高性能的方法有哪些?

1. 合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。
2. 减少css嵌套,最好不要嵌套三层以上。
3. 不要在ID选择器前面进行嵌套,ID本来就是唯一的而且权限值大,嵌套完全是浪费性能。
4. 建立公共样式类,把相同样式提取出来作为公共类使用。
5. 减少通配符*或者类似[hidden="true"]这类选择器的使用,挨个查找所有...这性能能好吗?
6. 巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。
7. 拆分出公共css文件,对于比较大的项目可以将大部分页面的公共结构样式提取出来放到单独css文件里,这样一次下载 后就放到缓存里,当然这种做法会增加请求,具体做法应以实际情况而定。
8. 不用css表达式,表达式只是让你的代码显得更加酷炫,但是对性能的浪费可能是超乎你想象的。
9. 少用css rest,可能会觉得重置样式是规范,但是其实其中有很多操作是不必要不友好的,有需求有兴趣,可以选择normolize.css。
10. cssSprite,合成所有icon图片,用宽高加上background-position的背景图方式显现icon图,这样很实用,减少了http请求。
11. 善后工作,css压缩(在线压缩工具 YUI Compressor)
12. GZIP压缩,是一种流行的文件压缩算法。

性能优化

> 1. 避免使用@import,外部的css文件中使用@import会使得页面在加载时增加额外的延迟。

首先,使用@import引入css会影响浏览器的并行下载。使用@import引用的css文件只有在引用它的那个css文件被下载,解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析,构建render tree等一系列操作,这就导致浏览器无法并行下载
所需的样式文件。
其次,多个@import会导致下载顺序紊乱,在IE中,@import会引发资源文件的下载顺序被打乱,即排列在@import后面的js文件优先于@import下载,并且打乱甚至破坏@import自身的并行下载。
所以不要使用这一方法,使用link标签就行了。

> 2.避免过分重排

  • 浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构的进程叫做reflow
  • 浏览器根据定义好的样式来计算,并将元素放到该出现的位置上,这个过程叫做reflow
  • 页面上任何一个节点触发来reflow,会导致他的子节点和祖先节点重新渲染
  • 导致reflow发生的情况
 1. 改变窗口的大小  
 2. 改变文字的大小
 3. 添加 删除样式表
 4. 内容的改变 输入框输入内容也会
 5. 伪类的激活
 6. 操作class属性
 7. 脚本操作dom js改变css类
 8. 计算offsetWidth和offsetHeight
 9. 设置style属性
 10.改变元素的内外边距 
  • 常见重排元素
 1. 大小有关的 width,height,padding,margin,border-width,border,min-height
 2. 布局有关的 display,top,position,float,left,right,bottom
 3. 字体有关的 font-size,text-align,font-weight,font-family,line-height,white-space,vertical-align
 4. 隐藏有关的 overflow,overflow-x,overflow-y
  • 减少reflow对性能的影响的建议
 1. 不要一条条的修改dom的样式,预先定义好class,然后修改dom的classname
 2. 不要修改影响范围较大的dom
 3. 为动画元素使用绝对定位
 4. 不要table布局,因为一个很小的改动会造成整个table重新布局
 5. 避免设置大量的style属性,通过设置style属性改变节点样式的话,每一次设置都会触发一次reflow,所以最好使用class属性
 6. 如果css里面有计算表达式,每次都会重新计算一遍,触发一次reflow

> repaint

  1. 当一个元素的外观被改变,但是布局没有改变的情况
  2. 当元素改变的时候,不影响元素在页面中的位置,浏览器仅仅会用新的样式重绘此元素
  3. 常见的重绘元素
 - 颜色 color,background
 - 边框样式 border-style,outline-color,outline,outline-style,border-radius,box-shadow,outline-width
 - 背景有关 background,backgound-image,background-position,background-repeat,background-size

> CSS动画

  1. css动画启用GPU加速,应用GPU的图形性能对浏览器中的一些图形操作交给GPU完成。canvas2D,布局合成,css3转换,css3d变换,webGL,视频
  2. 2d加速
  3. 3d加速

> 文件压缩

性能优化时最容易想到的,也是最常见的方法,就是文件压缩,这一方案往往效果显著
文件的大小会直接影响浏览器的加载速度,这一点在网络较差时表现尤为明显,构建工具webpack,gulp/grunt,rollup,压缩之后能够明显减少,可以大大降低浏览器的加载时间。

> 去除无用CSS

虽然文件压缩能够降低文件大小,但css文件压缩通常只会去除无用的空格,这样就限制来css文件的压缩比例。如果压缩后的文件仍然超过来预期的大小,可以试着找到并删除代码中无用的css。
一般情况下,会存在这两种无用的CSS代码:

  1. 不同元素或者其他情况下的重复代码,
  2. 整个页面内没有生效的CSS代码

> 有选择地使用选择器

css选择器的匹配是从右向左进行的,这一策略导致来不同种类的选择器之间的性能也存在差异。相比于 #markdown-content-h3,显然使用 #markdown.content h3时,浏览器生成渲染树所要花费的时间更多。因为后者需要先找到DOM中的所有h3元素,再过滤掉祖先元素不是.content的,最后过滤掉.content不是#markdown的。试想,页面中的元素更多,那么匹配所要花费的时间代价自然更高。
显得浏览器在这一方面做了很多优化,不同选择器的性能差别并不明显,甚至可以说差别甚微,此外不同选择器在不同浏览器中的性能表现也不统一,在编写css的时候无法兼顾每种浏览器,鉴于这两点,在使用选择器时,尽量记住以下几点:

 1. 保持简单,不要使用嵌套过多过于复杂的选择器
 2. 通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。
 3. 不要使用类选择器和ID选择器修饰元素标签,如:h3#markdown-content,这一多此一举,还会降低效率
 4. 不要为了追求速度而放弃可读性和可维护性

TIPS:为什么css选择器是从右向左匹配的?
css中更多的选择器是不会匹配的,所以在考虑性能问题时,需要考虑的是如何在选择器不匹配时提升效率,从右向左匹配就是为了达成这一目的的,通过这一策略能够使得css选择器在不匹配的时候效率更高。

> 减少使用昂贵的属性

在浏览器绘制屏幕时,所有需要浏览器进行操作或计算的属性相对而言都需要花费更大的代价,而页面发生重绘时,它们会降低浏览器的渲染性能。所以在编写css时,应该尽量减少使用昂贵属性,如:
box-shadow, border-radius, filter, 透明度, :nth-child等
当然并不是不要使用这些属性,这些都是经常使用的属性,只是这里可以作为一个了解。当有其他方案可以选择的时候,可以优先选择没有昂贵属性或昂贵属性更少的方案,这一网站的性能会在不知不觉中得到一定的提升。

> 硬件加速的好坏

  1. 仅仅依靠GPU还是不行的,许多动画还是需要CPU的介入,连接cpu和GPU的总带宽不是无限的,所以需要注意数据在cpu和GPU之间的传输,尽量避免造成通道的拥挤,要一直注意像素的传输。
  2. 一个重点是了解创建的合成层的数量,每一个层都对应来一个GPU纹理,太多的层会消耗很多内存。
  3. **chrome://flags/#composited-layer-borders**观察的地址。
  4. 每一个dom元素的合成层都会被标记一个额外的边框,这一就可以验证是否有了很多层
  5. 另一个重点是保持GPU和CPU之间传输量达到最小值,也就是说,层的更新数量最好是一个理想的常量,每次层更新的时候,一堆新的像素就可能需要传输给GPU。
  6. 因为为了高性能,动画开始之后避免层的更新也是非常重要的,避免动画进行中其他层一直更新导致拥堵。
  7. 也就是使用这些css属性来实现动画:transformation, opacity, filter
  8. 使用性能工具检测优化的合理性,timeline检测优化是否合理,还需要实现自动操作来做性能回归测试。
  9. 检测层数和层更新次数是非常有用的。

你可能感兴趣的:(CSS,CSS,CSS性能优化)