CSS优化和增加性能的方法有那些?
1.1 优化
实现⽅式有很多种,主要有如下:
- 内联⾸屏关键CSS
- 异步加载CSS
- 资源压缩
- 合理使⽤选择器
- 减少使⽤昂贵的属性
- 不要使⽤@import
1.1.1 内联首屏关键css
在打开⼀个⻚⾯,⻚⾯⾸要内容出现在屏幕的时间影响着⽤⼾的体验,⽽通过内联 css 关键代码能够使浏览器在下载完 html 后就能⽴刻渲染
⽽如果外部引⽤ css 代码,在解析 html 结构过程中遇到外部 css ⽂件,才会开始下载 css 代码,再渲染
所以, CSS 内联使⽤使渲染时间提前
注意:但是较⼤的 css 代码并不合适内联(初始拥塞窗⼝、没有缓存),⽽其余代码则采取外部引⽤⽅式
1.1.2 异步加载css
在 CSS ⽂件请求、下载、解析完成之前,CSS 会阻塞渲染,浏览器将不会渲染任何已处理的内容
前⾯加载内联代码后,后⾯的外部引⽤ css 则没必要阻塞浏览器渲染。这时候就可以采取异步加载的⽅案,主要有如下
- 使⽤javascript将link标签插到head标签最后
// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插⼊到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[
document.head.childNodes.length - 1 ].nextSibling );
- 设置link标签media属性为noexis,浏览器会认为当前样式表不适⽤当前类型,会在不阻塞⻚⾯渲染的情况下再进⾏下载。加载完成后,将 media 的值设为 screen 或 all ,从⽽让浏览器开始解析CSS
<link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">
通过rel属性将link元素标记为alternate可选样式表,也能实现浏览器异步加载。同样别忘了加载完成之后,将rel设回stylesheet
1 <link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">
1.1.3 资源压缩
利⽤ webpack 、gulp/grunt 、rollup 等模块化⼯具,将 css 代码进⾏压缩,使⽂件变⼩,⼤⼤降低了浏览器的加载时间
1.1.4 合理使用选择器
css 匹配的规则是从右往左开始匹配,例如 #markdown .content h3 匹配规则如下:
- 先找到h3标签元素
- 然后去除祖先不是.content的元素
- 最后去除祖先不是#markdown的元素
如果嵌套的层级更多,⻚⾯中的元素更多,那么匹配所要花费的时间代价⾃然更⾼
所以我们在编写选择器的时候,可以遵循以下规则:
- 不要嵌套使⽤过多复杂选择器,最好不要三层以上
- 使⽤id选择器就没必要再进⾏嵌套
- 通配符和属性选择器效率最低,避免使⽤
1.1.5 减少使用昂贵的属性
在⻚⾯发⽣重绘的时候,昂贵属性如 box-shadow / border-radius / filter /透明度/ :nth-child 等,会降低浏览器的渲染性能
1.1.6 不要使用@import
css样式⽂件有两种引⼊⽅式,⼀种是 link 元素,另⼀种是 @import
@import 会影响浏览器的并⾏下载,使得⻚⾯在加载时增加额外的延迟,增添了额外的往返耗时
⽽且多个 @import 可能会导致下载顺序紊乱
⽐如⼀个css⽂件 index.css 包含了以下内容: @import url("reset.css")
那么浏览器就必须先把 index.css 下载、解析和执⾏后,才下载、解析和执⾏第⼆个⽂件reset.css
1.1.7 其他
- 减少重排操作,以及减少不必要的重绘
- 了解哪些属性可以继承⽽来,避免对这些属性重复编写
- cssSprite,合成所有icon图⽚,⽤宽⾼加上backgroud-position的背景图⽅式显现出我们要的icon图,减少了http请求
- 把⼩的icon图⽚转成base64编码
- CSS3动画或者过渡尽量使⽤transform和opacity来实现动画,不要使⽤left和top属性
1.2 性能
- 加载性能
- css 压缩:将写好的 css 进行压缩打包,可以减少文件体积
- css 单一样式:需要下边距和左边距的时候,很多都会选择写上上下左右都写,其实写个下和左的样式即可
- 减少使用@import:建议使用 link,因为后者在页面加载时一起加载,而@import 是等待页面加载完成之后在进行加载
- 选择器性能
- 关键选择器(key selector):选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分),css 选择器是从右到左进行匹配的,当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否指定的元素等等
- 如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签,过滤掉无关的规则(这样样式系统就不会浪费时间去匹配他们了)
- 避免使用通配规则,如*,这样会让浏览器计算次数惊人,只对需要用到的元素进行选择
- 尽量少的去对标签进行选择,而是用 class 类
- 尽量少的去使用后代选择器,降低选择器的权重值,后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素
- 了解那些属性是可以通过继承而来的,然后避免对这些属性重复指定规则
- 渲染性能
- 慎重使用高性能属性:浮动/定位
- 尽量减少页面重排/重绘
- 去除空规则:*:{},空规则的产生原因一般来说是为了预留样式,去除这些空规则无疑能减少 css 文档体积
- 属性值为 0 时,不加单位
- 属性值为浮动小数 0.**,可以省略小数点之前的 0
- 标准化各种浏览器前缀:带浏览器前缀的在前,标准属性在后
- 不使用@import 前缀,它会影响 css 的加载速度
- 选择器优化嵌套,尽量避免层级过深
- css 雪碧图,同一页面相近的部分的小图标,方便实用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚
- 正确使用 display 的属性,由于地 display 的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能
- 不滥用 web 字体,对于中文网站来说 WebFont 可能很陌生,国外却很流行,web fonts 通常体积庞大,而且一些浏览器在下载 web fonts 时候会阻塞页面渲染,损耗性能
- 可维护性/健壮性
- 将具有相同属性的样式抽离出来,整合并通过 class 在页面中进行使用,提高 css 的可维护性
- 样式与内容分离:将 css 代码定义到外部 css 中