Skip to content

CSS的性能优化

精灵图

将多个小图片拼接到一个图片中。通过 background-position 和元素尺寸调节需要显示的背景图案。

优点:

  • 减少 HTTP 请求数,极大地提高页面加载速度
  • 增加图片信息重复度,提高压缩比,减少图片大小

缺点:

  • 图片合并麻烦
  • 维护麻烦,修改一个图片可能需要从新布局整个图片,样式
  • 缩放调整图标大小比较麻烦

FOUC

Flash Of Unstyled Content:用户定义样式表加载之前浏览器使用默认样式显示文档,用户样式加载渲染之后再从新显示文档,造成页面闪烁。

解决方法:把样式表放到文档的 head

重绘和回流

参考:

重绘

由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, color、background-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。

回流

部分渲染树(或者整个渲染树)布局或者几何属性改变时,需要重新分析并且节点尺寸需要重新计算。这被称为回流。注意这里至少会有一次回流-初始化页面布局

回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。

回流必定会发生重绘,重绘不一定会引发回流。

下面是一些重绘和回流的触发场景

  • 添加、删除、更新 DOM 节点
  • 通过 display: none 隐藏一个 DOM 节点-触发重排和重绘
  • 通过 visibility: hidden 隐藏一个 DOM 节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的 DOM 节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

浏览器批量更新

现代浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能有会影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值。

主要包括以下属性或方法:

  • offsetTop、offsetLeft、offsetWidth、offsetHeight
  • scrollTop、scrollLeft、scrollWidth、scrollHeight
  • clientTop、clientLeft、clientWidth、clientHeight
  • width、height
  • getComputedStyle()
  • getBoundingClientRect()

减少重绘与回流

CSS方面

  • 使用transform代替position,选择最多引起重绘而不是回流的属性,如visibility优于display:none
  • 尽量避免使用table布局
  • 避免使用css表达式
css
left: expression(document.body.offsetWidth - 180   "px")
  • 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe等标签,浏览器会自动将该节点变为图层。
  • CSS3硬件加速

JS方面

  • 避免频繁操作样式,最好将多个改动统一处理
  • 避免频繁操作DOM,可以在documentFragment上进行改动
  • 避免频繁读取会引发回流/重绘的属性,使用变量将结果缓存起来

硬件加速

参考

概念

定义:调用GPU代替CPU完成绘制的计算工作,从工作分摊和绘制机制优化来提升绘制速度。

常见的触发硬件加速的css属性:

  • transform
  • opacity
  • filters
  • Will-change
css
.example{
   -webkit-transform: translate3d(250px,250px,250px)
   rotate3d(250px,250px,250px,-120deg)
   scale3d(0.5, 0.5, 0.5);
}
/* 虽然没有用到这些属性,也可以欺骗浏览器开启GPU */
.example {
   transform: translateZ(0);
}
.example {
   backface-visibility: hidden;
   perspective: 1000;
}

.example {
   transform: translate3d(0, 0, 0);
}

优点

使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。

缺点

参考: CSS3开启硬件加速及利弊

如果你为太多元素使用css3硬件加速,会导致内存占用较大,会有性能问题。

在GPU渲染字体会导致抗锯齿无效。这是因为GPU和CPU的算法不同。因此如果你不在动画结束的时候关闭硬件加速,会产生字体模糊。

在Webkit内核的浏览器中,硬件加速会把需要渲染的元素放到特定的『Composited Layer』中,表示放到了一个新的『复合层(composited layer)』中渲染。

因此使用3D硬件加速提升动画性能时,最好给元素增加一个z-index属性,人为干扰复合层的排序,可以有效减少chrome创建不必要的复合层,提升渲染性能,移动端优化效果尤为明显