Skip to content

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标签最后
js
// 创建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
css
 <link rel="stylesheet" href="mystyles.css" media="noexist" onload="this.media='all'">

通过rel属性将link元素标记为alternate可选样式表,也能实现浏览器异步加载。同样别忘了加载完成之后,将rel设回stylesheet

css
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 中