回流(Reflow)和重绘(Repaint)是浏览器在渲染页面时发生的两个重要事件,它们对于页面性能和用户体验有着重要影响。
回流(Reflow):
回流是浏览器渲染过程中最消耗性能的一种操作。当 DOM 的变化影响到元素的几何属性(宽和高)或者边距、填充、边框、背景色等,或者触发了布局变化时,浏览器就需要重新计算元素的几何属性,这个过程就叫做回流。回流会从页面的左上角开始,然后在整个渲染树中向下进行,直到到达页面中的每一个像素。
重绘(Repaint):
重绘是指浏览器重新绘制页面上的一个或多个像素点。当 DOM 的变化影响到元素的背景色、文字颜色、边框颜色等时,浏览器就需要重新绘制这些像素点。重绘比回流轻量级,因为它不需要重新计算元素的几何属性。
减少回流和重绘的方法有:
- 批量处理DOM操作:隐藏DOM元素,对该元素进行所有的操作,最后再显示该元素。因对display:none的元素进行操作不会引起回流、重绘,所以只要操作只会有2次回流。
- 避免触发同步布局事件:因为在读取一些精确数据的时候,比如offsetTop的时候,浏览器会清空DOM操作事件队列,所以需要用到精确数据的时候,可以先保存读取的数据,在操作保存的数值后,再赋值给offsetTop。
- 对于复杂运动效果,使它脱离文档流,避免频繁触发重绘回流。
- 使用CSS3动画代替JavaScript动画。CSS3动画可以避免触发布局重排和重绘,从而提高页面性能。比如使用translate实现动画,不会引发重绘回流。
- 利用浏览器的优化策略,减少对style信息的请求。
- 避免频繁的触发style更改:如果可能的话,将需要更改的样式收集起来,一次性进行更改。
- 优化图片:图片是回流和重绘发生频繁的地方,可以通过优化图片大小和加载方式来减少回流和重绘。比如:避免一次性加载大量图片,可以使用懒加载等技术来延迟加载图片。
- 使用虚拟DOM技术:虚拟DOM可以避免直接操作DOM,从而减少回流和重绘。
- 批量修改元素样式:通过一次修改多个样式属性,可以减少因样式变化而引起的回流和重绘。
- 避免使用table布局:table布局的回流和重绘比较频繁,因此尽量避免使用table布局。
- 优化JavaScript代码:避免在循环中频繁操作DOM,可以使用事件代理等技术来减少事件处理器的数量。
- 使用requestAnimationFrame技术:requestAnimationFrame可以将样式变化和DOM操作集中在一次重绘中进行,从而避免频繁的回流和重绘。
减少回流和重绘的次数,从而提高页面性能。