性能,这个词如今被炒的很热,也是每个开发者,由“知道”、“会做”之后必经的一个“怎样做好”的阶段。性能关乎用户在不同设备和不同网络状态下的体验。也被多方面因素所影响。此文说说css方面怎样做到高性能。

高性能css

Html和css本身的性能问题并不突出,在提高可读性和可维护性的前提下,如果能让代码运行和解析的速度更快,则是锦上添花了。

一、使用高效css选择器

简单来说,能被浏览器快速解析和匹配的css选择器,就是高效的选择器。

首先要知道浏览器如何解析css

举个例子:.nav ul.list li div{}

我们常见的思维是,先去找到nav这个类,再找类包含的ul,再找ul中类为list的后代所有li中所有的div,简而言之,就是从左到右。可事实是这样么?么?么?~

事实是相反的!意味着什么呢?就是说它不是从第一个开始去慢慢的缩小范围,而是从div这个“裸奔”的盒子开始,相当于遍历,然后再找到li,以此类推,好吧不用我形容你应该知道这当中的消耗。理解这一原理非常重要,高效的选择器意味着匹配更快,查找次数更少。所以我们定义选择器时,应该让第一次匹配时的数量达到最少,并且让整体的匹配查找次数最少。

以上这些解释恰恰遵循了这样一些原则

(1)避免使用通配符

(2)避免使用标签选择器和单个属性选择器作为关键选择器

(3)不要在id选择器前加标签名

(4)尽量不要在选择符定义过多层级,层级越少,同时也降低了css和dom结构的耦合程度,提高样式的可维护性

(ps:老实说上面的这些“禁忌”你是不是都有犯过?~)

做个小结,以上所说,有两点需要知道,第一点在开头就已经提到,css的性能问题表现的并不突出,特别是在小项目中,所以,可维护性为先;第二点是虽然定义id选择器,有唯一性的优势,但是一个页面只能定义唯一id,定义过多id会使重用性降低,维护更困难,所以不建议多用id。

二、css相关的图片处理

现在的网页当中,图片所占的比重以及它的重要性大家都知道。那么如何处理好图片以及如何为图片设置样式,才能让用户打开网页时体验更好呢?下面给出一些意见:

(1)不给图片设置尺寸

在我个人的从业经历当中,有过这样的情况,我按照设计稿做好了页面,交给后台去测试,他就突然跑过来跟我说:hi,你看,这儿出状况了,我一看,坏菜,图片出格了,我才想起没有给图片定义宽高(直接从设计稿里切的也不需要),然后就犯错了似的在css样式里定义了宽高。以至于后来我把这个作为下次再做页面时候的注意事项。当我看到这一条意见的时候,才更知一二。

来看解释,第一、设计人员为了画面的精美,会制作一些超出需求尺寸的图片;第二、同一张图片可能会在页面不同地方多次使用,比如缩略图、正常图、大图。问题来了,如果图片原始尺寸和实际需求不同,在使用过程中就会存在性能问题,利用样式缩放会带来cpu的额外计算过程,增加了图片在浏览器的渲染时间,网络传输过程也会占更多带宽,增加下载时间。因此,最佳做法是,为需要的部分单独做一套图片,初始页面加载时就能更快展示。

(2)使用css“雪碧图“

是将零散的图片合并成一张大图,在利用css进行背景定位。好处是减少请求数,提高了图片整体的加载速度。

但它也存在一些缺点:

比如,多张图片合并成大图,需要精确计算,仔细的调整位置,单纯手工制作是一件很复杂的事情。(所幸现在有一些工具可以帮我们做)

另外,维护过程复杂,要尽量让已有的图片保持原来的位置不变,如果是背景图的尺寸发生变化导致原有区域无法放置,那就只好放弃,如果非要在原有位置修改,则剩余的图片样式都需要修改,是很繁琐的过程。新加的图片最好放在最后面。

还有就是使用不当会导致性能问题,最大的问题就是内存消耗。如果制作过程不做任何的规划,随意摆放,则可能会使图片变得相当大,从而很占内存。

下面是一些最佳实践:

1、在项目后期应用css sprite技术

因为一般在开发过程中,会比较频繁的修改或者更换图片,如果这个时候使用sprite技术,就会增加很多开发成本。

2、合理组织“雪碧”图

如果要把所有的图片放在一张图上面,也会有不妥,维护方面也不会很方便。组织背景图主要按照模块和背景图的风格来划分。比如,作为展示的缩略图放在一起,评论、点赞、上下箭头等图标放在一起等。

3、控制“雪碧”图的尺寸和大小

因为大尺寸的图片会占用大量的内存,所以要控制在合理尺寸,推荐长宽相乘不超过2500,大小在200kb内

4、合理控制背景图单元间的距离及背景图位置

这个原则是为了防止在背景图比元素大小更小的时候,区域出现别的无关背景图

5、借助相关工具处理sprite

三、减少css的代码量

提高网站整体加载速度的一个重要手段,就是提高代码文件的网络传输速度。除了代码压缩,精简代码也是一种手段。

(1)定义简洁的css规则

合并相关规则,定义简洁的属性值

合并规则是指比如font-family、font-size、font-weight等等,可以合并为font。 简洁属性值,比如颜色值:color,#33AAFF可以简化为#3AF等。

(2)合并相同定义

网页中总会有一些模块有较高相似度,则可把同样的部分共用一次定义,不同的部分再单独定义。而且在css中,很多属性是可以继承的,则只需要在合适的地方定义一次即可。

(3)删除无效的定义

无效的定义,并不会影响页面功能显示,但会影响页面展示的性能,增加代码量的同时,也增加了浏览器解析代码的时间。无效的定义包括无效的规则及无效的样式属性,一般是开发过程中引入的,而从直观上无法判断,这情况,可以用工具,chrome自带的工具就可以查找css中的无效样式。。

其他css高性能实践

(1)避免使用@import

@import导入的新样式文件会阻止页面的并行下载,这样增加了文件的整体加载时间。

(2)避免使用IE浏览器独有样式:图片滤镜和css表达式

图片滤镜的使用会在图片加载时阻塞浏览器的加载和渲染,并会增加额外的内存开销。 Css表达式的作用是动态设置css属性,表达式不只是有兼容性问题,还有性能问题,例如浏览器大小改动、窗口改动时,会使得浏览器频繁计算,性能消耗极大。同样的效果可以用javascript来实现。

css3最佳实践

查看浏览器支持情况

在我们使用css3的过程中,问的最多的一个问题可能就是:兼容性如何?没办法,随着css的发展,它可以为我们之前遇到的很多不好解决的问题提供一个更好的方案,让我们忍不住去想能不能那样去做。PC端有饱受诟病的IE系列,到了移动端会好很多,但有些还是不太好。所以,查看浏览器支持情况几乎成了必备动作。 如果使用的特性仅仅是装饰点缀性的效果,不影响大局,则不需要考虑太多兼容问题,如果是出于设计要求,必须支持所有浏览器,则要特别的关注一下了。 开发者可以选择比如:caniuse.com、css3 Click Chart、css contents and browser compatibility这些在线工具来查看兼容性。

添加必要的浏览器前缀

对于刚使用css不久的朋友来说,如果偶尔在某网站源码当中看到诸如:“-webkit-、-moz-”等,可能会觉得很奇怪,这是什么?它们是对应不同的浏览器厂商所加上的前缀。

因为浏览器在支持css3时,可能仅仅实现了标准定义的一个早期版本,所以,尚不支持标准写法,给代码添加浏览器前缀也是无奈之举,会使得代码更多,更难维护。

但也不是为了“完美”而一定要去兼容所有的浏览器,一般可以按照浏览器或者系统的版本的市场占有率和目标用户使用浏览器的比例,来决定加不加前缀以及加几种前缀。而且相信随着逐步的发展,系统、浏览器的不断升级、更新,需要使用前缀的情况会减少。

问题又来了,既然需要添加必要的前缀,说明有些时候还是很有必要,那不得不加的情况下,那不是挺麻烦的?同样的一条规则要写三四遍,可能很多地方都要用,如何是好?别急,下面是几个对策:

1、使用工具来添加css属性的浏览器前缀

Prefixr,可以在开发的后期对代码进行处理。它会自动的添加需要的前缀和删去不必要的前缀。

Autoprefixer,如果想要在开发过程中更多的自主性,可以使用这个工具,开发者可以自定义浏览器支持范围,它也有多种使用方式,可以集成到多个开发环境中。 此外还有几种工具可供使用:cssFxcss Agent-prefix-free

2、借助css预处理技术

目前流行的有sass、less,具体方法是,针对css3样式特性定义一份模板样式。 优点是:避免大量重复代码,只需要维护一份定义。

3、不要过度添加浏览器前缀

有些开发者为了兼容所有浏览器,不管什么情况都为css代码加上了所有浏览器的前缀,这是一种消极的编码方式,增加了太多的重复代码,降低了浏览器的解析性能,增加了复杂度,同时某些前缀的属性可能没有被浏览器支持过。

4、添加css3标准属性定义

何为标准属性定义呢?就是不需要任何浏览器前缀,大家可能都会注意到,很多使用css3的地方都会在最后的地方写标准属性定义,为什么呢?因为当浏览器支持标准属性时,它可以覆盖前面添加了前缀的定义,css3中的属性标准定义才是符合规范的定义,添加了浏览器前缀的定义会随着浏览器的更新逐渐被淘汰。

当然,还有一点需要注意的是,某些属性,目前是属于Only webkit或者Only firefox的,那么就没有必要再写上标准定义及其他浏览器前缀了。

做好css3中新特性的兼容处理

说到兼容,就会提到低版本IE,比如很常见的圆角、透明图片等,有时候我们会给它们降级的处理,比如filter或者javascript,使用box-sizing、transform,推荐使用Modernizr,这个框架中包含了很多css3新特性的兼容方案。

无论是哪种方案,都会带来性能上的损耗,不能毫无章法的滥用,仍然是需要大家去权衡和选择。推荐一个如何更有效率的使用HTML5的建议网站:html5please。网站按照使用的方式把css3中的新特性分成了三类:

(1)直接使用

包含了大部分新特性,有些特性本身不会影响兼容性,如border-radius、media queries等,有些需要添加降级处理,如多背景图,要设置一个单背景图或者背景色作为备选。

(2)谨慎使用

这部分主要是性能问题,例如框阴影应用于占用很大区域的元素,页面滚动或鼠标悬停时,会引起不小性能问题。

(3)避免使用

这部分因为它们可能仅支持某个浏览器,比如倒影,则需要避免使用。

综上所述,css能够用来提高性能的方法还是蛮多的,但我们很容易忽略它们,因为它们所带来的影响似乎没有那么明显,而且,很多人可能为了图方便,任意挥洒着自己的才华,想怎么写就怎么写,能达到效果就行,这也有点小消极哈,忘了你的优秀工程师目标了麻?!~~css规则虽不不难,真正写好也不易,还是要有些追求极致的精神滴。诸君且写且珍惜吧!~