重排/回流(Reflow):当DOM的变化影响了元素的几何信息,浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。表现为重新生成布局,重新排列元素。 重绘(Repaint): 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。表现为某些元素的外观被改变 单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分
重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。
『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。
如何触发回流和重绘?
任何改变用来构建渲染树的信息都会导致一次回流或重绘:
添加、删除、更新DOM节点 通过display: none隐藏一个DOM节点-触发回流和重绘 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化 移动或者给页面中的DOM节点添加动画 添加一个样式表,调整样式属性 用户行为,例如调整窗口大小,改变字号,或者滚动。 如何避免回流和重绘?
集中改变样式,不要一条一条地修改 DOM 的样式。
不要把 DOM 结点的属性值放在循环里当成循环里的变量。
为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。
不使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。
尽量只修改position:absolute或fixed元素,对其他元素影响不大
动画开始GPU加速,translate使用3D变化
提升为合成层
将元素提升为合成层有以下优点:
合成层的位图,会交由 GPU 合成,比 CPU 处理要快 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层 对于 transform 和 opacity 效果,不会触发 layout 和 paint 提升合成层的最好方式是使用 CSS 的 will-change 属性:
1 2 3 #target { will-change: transform; }