js重绘和回流(重排)

一、浏览器渲染过程?

浏览器渲染过程

浏览器生成渲染树的过程

二、什么是重绘?回流(重排)?

定义
  • 重排:重新生成布局。当DOM 的变化影响了元素的几何属性(宽和高)--比如改变边框宽度或给段落增加文字导致行数增加--浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。
  • 重绘:重新绘制。完成重排后,浏览器会重新绘制受影响的部分到屏幕中。这个过程称为重绘。
重排与重绘的关系

重排一定会导致重绘,重绘不一定导致重排。如果DOM变化不影响几何属性,元素的布局没有改变,则只发生一次重绘(不需要重排)。

哪些情况会发生重绘,回流?

---不同的条件下发生重排的范围及程度会不同 :

  1. 页面初始渲染
  2. 改变字体,改变元素尺寸(宽、高、内外边距、边框,改变元素位置等
    各种情况:
  • 设置 style 属性的值
  • 激活 CSS 伪类,比如 :hover
  • 操作 class 属性
  • css3的某些属性
  1. 改变元素内容(文本或图片等或比如用户在input框中输入文字)
  2. 添加/删除可见DOM元素(注意:如果是删除本身就display:none的元素不会发生重排;visibility:hidden的元素显示或隐藏不影响重排)
  3. fixed定位的元素,在拖动滚动条的时候会一直回流
  4. 调整窗口大小(Resizing the window)
  5. 计算 offsetWidth 和 offsetHeight 属性
    浏览器是聪明的,当对以下属性进行操作的时候:
    包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。
    浏览器不会马上操作它们,而是会先缓存在队列中,有一定时间顺序去执行这些操作,但是在这过程中我们需要去获取在该队列中的属性时,浏览器为取得正确的值就会触发重排。这样就使得浏览器的优化失效了。
    所以,在多次使用这些值时应进行缓存。

三、如何减少重绘和回流(重排)

CSS中避免回流、重绘
  • 尽可能在DOM树的最末端改变class
  • 避免设置多层内联样式
  • 动画效果应用到position属性为absolute或fixed的元素上
  • 避免使用table布局
  • 使用css3硬件加速,可以让transform、opacity、filters等动画效果不会引起回流重绘
JS操作避免回流、重绘
  • 避免使用JS一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称
  • 避免频繁操作DOM,使用文档片段创建一个子树,然后再拷贝到文档中
  • 先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘
  • 避免循环读取offsetLeft等属性,在循环之前把它们存起来
  • 对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容