页面的重排和回流(提升移动端网页性能)

一、重绘重排的概念:

  1. 重绘的意思是:重新绘制,如:颜色发生变化,
  2. 重排(回流)的意思是:重新排列,即布局会受影响,如:用js动态改变了元素的宽或高,就会影响其它元素的位置,这叫重新排列。

 

二、什么时候引起重绘,什么时候引起重排:

1、重排(回流):回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况:

  • 页面一开始渲染的时候(这肯定避免不了)
  • DOM树的结构变化:添加或删除可见的DOM元素
  • DOM元素的几何属性变化:如外边距、内边距、边框厚度、宽高、等几何属性)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
  • 窗口属性的获取和尺寸改变:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、 clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)
  • Display:的变化。

2、重绘

·DOM元素的字体颜色、改变visibility、outline、背景色。重绘不会带来DOM元素的重新计算,所以重绘并不一定伴随重排(回流),但是重排一定会引起浏览器的重绘

 

三、问题:

重绘,重排太过频繁,就会影响网页的执行性能。亲,你想想:你的页面本来一次可以重排好,你得多重排一次,那肯定是影响性能的。重绘一次就可以,你非得多重绘继承,那肯定也是影响性能的。

跟生活中一样。

重绘:你不停地擦掉重画,擦掉重画,肯定不如一次画到位好

重排:你总是重复性的把某个物体不停地挪动。跟家里的家具要换位置的道理一样。你如果想不来,今晚回去思考一下:假定你要把家里的家具重新布局(从A布局变成B布局),你在家具搬动的过程中,可以出几套搬动方案。看看哪一种搬动方案是挪动家具次数最少的,那么这种方案就是重排的最优方案。

 

四、浏览器的性能优化方案

浏览器也是很聪明的,由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:

 

offsetTop、offsetLeft、offsetWidth、offsetHeight

scrollTop、scrollLeft、scrollWidth、scrollHeight

clientTop、clientLeft、clientWidth、clientHeight

getComputedStyle()

getBoundingClientRect()

 

以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。这也是为什么在获取这些值时会引起重排(回流)、重绘的原因,因此,我们在修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列。如果要使用它们,最好将值先保存起来。

 

五、如何解决:

 

1、分离读和写的操作(避免触发同步布局事件):


let ulDom = document.getElementById(“box”);

var curLeft=ulDom .offsetLeft;

var curTop=ulDom .offsetTop;

ulDom .style.left=curLeft+1+'px';

ulDom .style.top=curTop+1+'px';

 

而不要这样写:

let ulDom = document.getElementById(“box”);

var curLeft=ulDom .offsetLeft;

ulDom .style.left=curLeft+1+'px';

var curTop=ulDom .offsetTop;

ulDom .style.top=curTop+1+'px';

 

因为,获取offsetLeft和offsetTop会导致浏览器强制清空队列,进行强制同步布局。

    

2、样式集中改变,而不要一个一个的改变(减少重绘重排)

   如:let ulDom = document.getElementById(“box”);

       ulDom.style.left = “100px”;

       ulDom.style.top = “200px”;

  最好改成如下(cssText):

    let ulDom = document.getElementById(“box”);

    ulDom.style.cssText = ‘left :100px;top:200px;’

    或者使用class名也可以

ulDom.className = “boxcls”;

 

3、批量修改DOM

1)、如果可以的话,在重排时,可以使用absolute脱离文档流,这样,元素的尺寸改变时,就不会影响其它元素了。先让元素absolute。然后给元素中放入若干个dom,再把元素的absolute去掉;

   如果可以的话,使用display:none(脱离文档流),等元素的样式属性改变完毕后,再让元素显示。

 2)、使用createDocumentFragment或拼接html字符串的方式进行DOM的增加。

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重绘重排是CSS渲染过程中的两个重要概念。 重绘(Repaint)指的是当元素的样式发生变化,但不影响其布局时,浏览器会将新样式应用到元素上,重新绘制元素的外观。重绘的开销相对较小,不会引起布局的变化。 而重排(Reflow)指的是当页面布局发生变化时,例如修改了元素的尺寸、位置、内容等,浏览器会重新计算并更新元素的几何属性(如大小、位置),然后重新布局页面重排的开销相对较大,因为它涉及到整个页面或部分页面的重新渲染。 重绘重排的区别在于是否引起布局的变化。重绘只会重新绘制元素的外观,而不会影响其周围元素的布局;而重排导致整个渲染树的重新构建和布局。 在性能优化方面,我们通常要尽量减少重排重绘的次数,因为它们会消耗大量的计算资源。一些常见的优化方法包括: 1. 使用 CSS3 动画或过渡代替 JavaScript 实现的动画效果,因为后者可能会导致频繁的重排重绘; 2. 使用类似 flexbox 和 grid 等布局技术,可以减少页面布局的复杂性,降低重排重绘的次数; 3. 避免频繁访问会引起重排重绘的属性,例如 offsetTop、offsetLeft、scrollTop、clientWidth 等; 4. 批量更新样式或布局,可以使用 CSS 类名的方式一次性修改多个元素的样式,而不是逐个修改; 5. 将需要执行多次重排的 DOM 操作尽量合并为一次,使用文档片段(DocumentFragment)进行缓存。 通过合理优化和减少重排重绘的次数,可以提升页面性能和响应速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值