一、基础概念
回流:当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。当页面布局和几何属性改变时就需要回流
重绘:当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
我们要注意的是:回流必将引起重绘,而重绘不一定会引起回流。
二、触发重绘,回流条件
我们先来看一下哪些属性会引发回流:
- 盒子模型相关属性会触发重布局
width height padding margin
display border-width border min-height - 定位属性及浮动也会触发重布局
top bottom left right
position float clear - 改变节点内部文字结构也会触发重布局
text-align overflow-y font-weight overflow
font-family line-height vertival-align white-space
font-size
触发重绘的属性:
color border-style border-radius visibility
text-decoration background background-image background-position
background-repeat background-size outline-color outline
outline-style outline-width box-shadow
三、新建dom的过程:
- 获取DOM后分割为多个图层
- 对每个图层的节点计算样式结果(Recalculate style--样式重计算)
- 为每个节点生成图形和位置(Layout--回流和重布局)
- 将每个节点绘制填充到图层位图中(Paint Setup和Paint--重绘)
- 图层作为纹理上传至GPU
- 符合多个图层到页面上生成最终屏幕图像(Composite Layers--图层重组)
四、创建图层的条件layer
- 3D或透视变换(perspective transform)CSS属性
- 使用加速视频解码的<video>节点,gif图
- 拥有3D(WebGL)上下文或加速的2D上下文的<canvas>节点
- 混合插件(如Flash)
- 对自己的opacity做CSS动画或使用一个动画webkit变换的元素
- 拥有加速CSS过滤器的元素
- 元素有一个包含复合层的后代节点(一个元素拥有一个子元素,该子元素在自己的层里)
- 元素有一个z-index较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
五、优化点
- 用translate替代top改变
- 用opacity替代visibility
- 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM的className
- 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来
- 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量,如offsetHeight,读取会引发回流
- 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
- 动画实现的速度的选择
- 对于动画新建图层,但是图层过多也会影响性能,只将需要重绘的部分做图层,其它尽量减少图层,will-change: transform也可以新建一个图层
will-change: transform可以新建一个图层,接下来将要干什么 - 启用 GPU 硬件加速
六、requestIdleCallback
window.requestAnimationFrame() // 下一帧
window.requestIdleCallback() // 下几帧时重新渲染
读写分离:读的时候不会触发layout,写的时候才会触发一次layout
七、cpu,gpu
高效的初衷是影响重绘不影响重排,而且能让gpu进行参与.
cpu和gpu的相同之处:两者都有总线和外界联系,有自己的缓存体系,以及数字和逻辑运算单元。两者都是为了完成计算任务而设计。
不同之处:cpu主要负责操作系统和应用程序,GPU负责显示相关的数据处理,
Gpu的活,Cpu都可以干,但是效率没有Gpu高