reflow与repaint

重流和重绘

重流就是页面的布局发生了彻彻底底的改变,元素位置或者宽高发生了变化,整个页面需要重新布局,这个时候就需要reflow。

重绘可能就是只绘一小部分,而不会绘制全部整个页面。

Repaint——屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。

Reflow——意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow )reflow 会从<html>这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。

 

DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。

 

注意:

1.display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。

2.reflow必然引起repaint,但是repaint不一定引起reflow

 

触发reflow

 

基本上来说,reflow有如下的几个原因:

Initial。网页初始化的时候。

Incremental。一些Javascript在操作DOM Tree时。

Resize。其些元件的尺寸变了。

StyleChange。如果CSS的属性发生变化了。

Dirty。几个Incremental的reflow发生在同一个frame的子树上。

 

下面是上述几个总结原因的具体体现,

当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:

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

2.元素位置改变,移动DOM的位置,或是搞个动画的时候;

3.元素尺寸改变——边距、填充、边框、宽度和高度

4.内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

5.页面渲染初始化;

6.浏览器窗口尺寸改变——resize事件发生时;

7.当你修改CSS样式的时候。

8.当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候。

9.当你修改网页的默认字体时。(文字撑开盒模型,盒子变大,挤开其他人)

 

多说两句关于滚屏的事,通常来说,如果在滚屏的时候,我们的页面上的所有的像素都会跟着滚动,那么性能上没什么问题,因为我们的显卡对于这种把全屏像素往上往下移的算法是很快。但是如果你有一个fixed的背景图,或是有些Element不跟着滚动,有些Elment是动画,那么这个滚动的动作对于浏览器来说会是相当相当痛苦的一个过程。你可以看到很多这样的网页在滚动的时候性能有多差。因为滚屏也有可能会造成reflow。

【简单来说,就是你需要保持背景图不变,但是呢,一些元素你又得把它向上移动,本来这是没什么的,但是背景图片再上一个屏幕被挡住的那一部分,在现在,需要绘制出来,所以这也是触发reflow的原因】

 

 

当然,我们的浏览器是聪明的,它不会像上面那样,你每改一次样式,它就 Reflow 或 Repaint 一次。一般来说,浏览器会把这样的操作积攒一批,然后做一次 Reflow ,这又叫异步 reflow 或增量异步 Reflow 。但是有些情况浏览器是不会这么做的,比如:Resize 窗口,改变了页面默认的字体,等。对于这些操作,浏览器会马上进行 Reflow 。----浏览器的渲染原理简介

 

 

1)不要一条一条地修改DOM的样式。与其这样,还不如预先定义好css的class,然后修改DOM的className。

// bad var left = 10, top = 10; el.style.left = left + "px"; el.style.top  = top  + "px"; // Good el.className += " theclassname"; // Good el.style.cssText += "; left: " + left + "px; top: " + top + "px;";

2)把DOM离线后修改。如:

  • 使用documentFragment 对象在内存里操作DOM
  • 先把DOM给display:none(有一次reflow),然后你想怎么改就怎么改。比如修改100次,然后再把他显示出来。
  • clone一个DOM结点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。

3)不要把DOM结点的属性值放在一个循环里当成循环里的变量。 不然这会导致大量地读写这个结点的属性。

4)尽可能的修改层级比较低的DOM 。当然,改变层级比较底的DOM有可能会造成大面积的reflow,但是也可能影响范围很小。

5)为动画的HTML元件使用fixed或absoult的position ,那么修改他们的CSS是不会reflow的。

6)千万不要使用table布局 。因为可能很小的一个小改动会造成整个table的重新布局。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值