理解两个概念 :
原理首先要了解css图层的概念,浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。在渲染DOM的时候,浏览器所做的工作实际上是:
- 获取DOM后分割为多个图层
- 对每个图层的节点计算样式结果(Recalculate style–样式重计算)
- 为每个节点生成图形和位置(Layout–回流和重布局)
- 将每个节点绘制填充到图层位图中(Paint Setup和Paint–重绘)
- 图层作为纹理上传至GPU
- 复合多个图层到页面上生成最终屏幕图像(Composite Layers–图层重组)
整个过程:
概念
当DOM元素影响了元素的几何属性(例如宽和高),浏览器需要重新计算元素的几何属性,同样其它元素的几何属性也会和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为“重排”。
完成重排后,浏览器会重新绘制受影响的部分到屏幕上中,该过程称为“重绘”。
引起重排的因素
- 改变窗口大小
- 改变文字大小
- 添加/删除样式表
- 内容的改变,(用户在输入框中写入内容也会)
- 激活伪类,如:hover
- 操作class属性
- 脚本操作DOM
- 计算offsetWidth和offsetHeight
- 设置style属性
常见的重排元素枚举:width height padding margin
display border-width border top
position font-size float text-align
overflow-y font-weight overflow left
font-family line-height vertical-align right
clear white-space bottom min-height
减少reflow
- 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className
- 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来
- 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量
- 尽可能不要修改影响范围比较大的 DOM
- 为动画的元素使用绝对定位 absolute / fixed
- 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
- 尽可能限制reflow的影响范围,尽可能在低层级的DOM节点上,上述例子中,如果你要改变p的样式,class就不要加在div上,通过父元素去影响子元素不好。
- 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性
- 实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局
- 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
- 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围
- 如果CSS里面有计算表达式,每次都会重新计算一遍,出发一次reflow
引起重绘的
常见的重绘元素
color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size
如何优化重绘
css3 动画是优化的重中之重。除了做到上面两点,减少 Reflow 和 Repaints 之外,还需要注意以下方面。
启用 GPU 硬件加速:transform: translate3d(10px, 10px, 0);