CSS性能

CSS压缩

CSS压缩并不是什么高端的姿势,但却很有用,其原理很简单,就是把我们CSS中没用的空白符等删去,达到缩减字符个数的目的。

我们有这样一段CSS脚本:

.test {
    background-color:#ffffff;
    background-image:url(a.jpg);
}

经过压缩后会变成这样

.test { background-color:#fff;  background-image:url(a.jpg)}

Gzip压缩

Gzip是一种流行的文件压缩算法,现在的应用十分广泛,尤其是在Linux平台,这个不止是对CSS,当应用Gzip压缩到一个纯文本文件时,效果是非常明显的,大约可以减少70%以上的文件大小(这取决于文件中的内容)。

Web服务器处理HTTP压缩的过程如下:
1. Web服务器接收到浏览器的HTTP请求后,检查浏览器是否支持HTTP压缩(Accept-Encoding 信息);

2. 如果浏览器支持HTTP压缩,Web服务器检查请求文件的后缀名;

3. 如果请求文件是HTML、CSS等静态文件,Web服务器到压缩缓冲目录中检查是否已经存在请求文件的最新压缩文件;

4. 如果请求文件的压缩文件不存在,Web服务器向浏览器返回未压缩的请求文件,并在压缩缓冲目录中存放请求文件的压缩文件;

5. 如果请求文件的最新压缩文件已经存在,则直接返回请求文件的压缩文件;

6. 如果请求文件是动态文件,Web服务器动态压缩内容并返回浏览器,压缩内容不存放到压缩缓存目录中。

利用继承

CSS的继承机制也可以帮我们再一定程度上缩减字节数,我们知道CSS有很多属性是可以继承的即在父容器设置了默写属性,子容器会默认也使用这些属性,因此如果我们希望全文字体尺寸是14px,大可不必为每个容器设置,只需要在body上设置就可以了。应用这个技巧,把CSS属性在可能的情况下提到父容器是可以帮我们节省CSS字节的,顺便说一下哪些属性可以继承。

所有元素可继承:visibility和cursor
内联元素和块元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction
块状元素可继承:text-indent和text-align
列表元素可继承:list-style、list-style-type、list-style-position、list-style-image
表格元素可继承:border-collapse
不可继承的:display、margin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before和unicode-bidi

css 选择器

 #yy > li { font-weight: bold }

按照我们惯常的理解,编译器应该是先查找idyy的节点,然后在他的所有直接子节点中查找类型(tag)为li的节点,将font-weight属性应用到这些节点上。

但是,不幸的是,恰恰相反,浏览器是从右往左来分析 class 的,它的匹配规则是从右向左来进行匹配的。这里,浏览器首先会查找页面上所有的li节点,然后再去做进一步的判断:如果它的父节点的idyy,则匹配成功。

由此可知,CSS 选择器的匹配远比我们想象的要慢的多,CSS的性能问题不容忽视。

#yy  li {font-weight: bold}

这个效率比之前的child selector效率更慢,而且要慢很多。浏览器先遍历所有的li节点,然后步步上溯其父节点,直到 DOM 结构的根节点(document),如果有某个节点的 idyy,则匹配成功,否则继续查找下一个li节点。

不要用标签或 class 来限制 ID 规则

这个应该是个常识,但很多同学都会误用,写出#test.info或者div#test这样的选择器,这个只能说是画蛇添足,id已经可以唯一而且最快的定位一个元素了。

不要用标签名限制 class 规则

这个估计被误用的更多,如div.info这样的写法,其实我们可以直接写为.info,从右到左解析的原因可以知道为什么其低效,如果直接使用class不能达到目的,一般情况下应该是class设计的有问题,CSS需要重构了。

尽量使用最具体的类别、避免后代选择器、属于标签类别的规则永远不要包含子选择器

这三条规则是想通的,因为从左到右解析关系,在CSS选择器中后代选择器非但没有帮我们加快CSS查找,反而后代选择器是 CSS中耗费最昂贵的选择器。 它的耗费是极其昂贵的—特别是当选择器在标签或通用类别中,能免则免。

优化回流和重绘

回流

浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构的进程叫做reflow。回流会导致浏览器重新计算整个文档,重新构建渲染树,这一过程会减低浏览器的渲染速度。

什么时候会导致reflow发生呢?
  • 改变窗口大小
  • 改变文字大小
  • 添加,删除样式表
  • 内容的改变(用户在输入框中写入内容也会)
  • 激活伪类,如:hover
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidthoffsetHeight
  • 设置style属性
优化回流
  • 尽可能限制reflow的影响范围,尽可能在低层级的DOM节点上通过父元素去影响子元素不好。
  • 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性。
  • 实现元素的动画,它的position属性,最好是设为absoultefixed,这样不会影响其他元素的布局。
  • 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
  • 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
  • 如果CSS里面有计算表达式,每次都会重新计算一遍,出发一次reflow

重绘

repaint是在一个元素的外观被改变,但没有改变布局的情况下发生的,如改变了visibilityoutlinebackground等。当repaint发生时,浏览器会验证DOM树上所有其他节点的visibility属性。

启用 GPU 硬件加速

GPUGraphics Processing Unit) 是图像处理器。GPU 硬件加速是指应用 GPU 的图形性能对浏览器中的一些图形操作交给 GPU 来完成,因为 GPU 是专门为处理图形而设计,所以它在速度和能耗上更有效率。

GPU 加速可以不仅应用于3D,而且也可以应用于2D。这里, GPU 加速通常包括以下几个部分:Canvas2D布局合成(Layout Compositing), CSS3转换(transitions)CSS3 3D变换(transforms)WebGL视频(video)

/*
 * 根据上面的结论
 * 将 2d transform 换成 3d
 * 就可以强制开启 GPU 加速
 * 提高动画性能
 */
div {
  transform: translate(10px, 10px);
}
div {
  transform: translate3d(10px, 10px, 0);
}

参考文章

浏览器重绘与重排的性能优化
优化CSS重排重绘与浏览器性能
常用CSS优化总结——网络性能与语法性能建议

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