浅析浏览器的回流与重绘 (Reflow & Repaint)

  在前端开发的日常中,与浏览器打交道也是其中最重要的一部分,所见即所得的特点,因为浏览器,才变得有意思起来,那么平时我们在开发的过程中,会遇到与浏览器相关的性能问题,其中有两个特性与页面的渲染以及性能是有关的,就是浏览器的回流和重绘,那么什么是回流,什么又是重绘呢?下面就来跟大家阐述一下:

  一、浏览器渲染步骤

  浏览器在接收到html和css后,渲染的步骤是:html经过渲染生成DOM树,css经过渲染生成css渲染树,两者再经过结合,生成render tree,浏览器就可以根据render tree进行画面绘制。

  如果浏览器从服务器接收到了新的css,需要更新页面的时候,需要经过什么操作呢?这就是回流reflow与重绘repaint所发生的步骤,因此,回流必定会引起重绘,但是重绘并不一定会引起回流。

 

  二、重绘

  当前元素的样式(背景颜色,字体颜色)发生改变的时候,我们只需要把改变的元素重新的渲染一下即可,重绘对于浏览器的性能较小。

  发生重绘的情形:改变容器的外观风格等,比如background:black等。改变外观,不改变布局,不会影响到其他的DOM。

  

  三、回流

  是指浏览器为了重新渲染部分或者全部的文档而重新计算文档中元素的位置和几何构造的过程。

 

  四、引起因素

  因为回流可能导致整个COM树的重新构造,所以是性能的一大杀手,一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流,下面是引起浏览器触发回流reflow的变化:

  页面首次渲染

  浏览器窗口大小发生改变

  元素尺寸或者位置发生改变

  元素的内容发生变化(文字数量或者图片大小)

  元素字体大小变化

  添加或者删除可见的DOM元素

  激活CSS伪类(如:hover)

  查询某些属性或调用某些方法

 

  五、优化方案

  css:

  1、避免使用table布局

  2、尽可能的在DOM树最末端改变class

  3、避免设置多层内联样式

  4、将动画效果应用到position属性为absolute或fixed已经脱离正常文档流的元素上(个人实际项目,手机端动画效果应用到absolute元素上时,浏览器也会发生回流效应,因此尽量不要使用js改变元素位置操作动画效果,手机端建议CSS3动画效果,由浏览器渲染引擎进行动画绘制,性能要高于JS控制)

  5、避免使用CSS表达式(如calc()动态设置元素宽高)

 

  js:

  1、避免频繁操作样式,最好是一次性重写style属性,或者将样式列表定义为class,一次性更改class属性

  2、避免频繁操作DOM,创建一个documentFragment,在其上面应用所有的DOM操作,最后再将其添加到文档中

  3、也可以先将元素设置为display:none,再进行相关DOM操作,操作结束后,再让它显示出来。因为在display:none元素上操作DOM,并不会引起浏览器的回流和重绘

  4、避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

  5、对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

posted @ 2018-05-29 14:27  沐小风  阅读(717)  评论(0编辑  收藏  举报