重绘和回流

1. 浏览器渲染机制

浏览器采用流式布局模型(Flow Based Layout)
浏览器会把HTML 解析成DOM,把CSS 解析成CSSOM,DOM 和CSSOM 合并就产生了渲染树(Render Tree)。
有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。
由于浏览器使用流式布局,对Render Tree 的计算通常只需要遍历一次就可以完成,但table 及其内部元素除外,他们可能需要多次计算,通常要花3 倍于同等元素的时间,这也是为什么要避免使用table 布局的原因之一。

2. 重绘

由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, color、background-color 等,重绘的代价是高昂的,因为浏览器必须验证DOM 树上其他节点元素的可见性。

3. 回流

回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及DOM 中紧随其后的节点、祖先节点元素的随后的回流。

<body>
	<div class="error">
	<h4>我的组件</h4>
	<p>
		<strong>错误:</strong>错误的描述…
	</p>
	<h5>错误纠正</h5>
	<ol>
		<li>第一步</li>
		<li>第二步</li>
	</ol>
	</div>
</body>

在上面的HTML 片段中,对该段落(< p >标签)回流将会引发强烈的回流,因为它是一个子节点。这也导致了祖先的回流(div.error 和body – 视浏览器而定)。
此外,< h5 >和< ol >也会有简单的回流,因为其在DOM 中在回流元素之后。大部分的回流将导致页面的重新渲染。
回流必定会发生重绘,重绘不一定会引发回流。

4. 浏览器优化

现代浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能有会影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值。
主要包括以下属性或方法:
1、offsetTop、offsetLeft、offsetWidth、offsetHeight
2、scrollTop、scrollLeft、scrollWidth、scrollHeight
3、clientTop、clientLeft、clientWidth、clientHeight
4、width、height
5、getComputedStyle()
6、getBoundingClientRect()
所以,我们应该避免频繁的使用上述的属性,他们都会强制渲染刷新队列。

5. 减少重绘与回流

CSS
1、使用transform 替代top
2、使用visibility 替换display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)。
3**、避免使用table 布局,**可能很小的一个小改动会造成整个table 的重新布局。
4、尽可能在DOM 树的最末端改变class,回流是不可避免的,但可以减少其影响。尽可能在DOM 树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。
5、避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多。

<div>
	<a> 
		<span></span>
	</a>
</div>
<style>
	span {
		color: red;
			} div > a > span {
				color: red;
			}
</style>

对于第一种设置样式的方式来说,浏览器只需要找到页面中所有的span 标签,然后设置颜色,但是对于第二种设置样式的方式来说,浏览器首先需要找到所有的span 标签,然后找到span 标签上的a 标签,最后再去找到div 标签,然后给符合这种条件的span 标签设置颜色,这样的递归过程就很复杂。所以我们应该尽可能的避免写过于具体的CSS 选择器,然后对于HTML 来说也尽量少的添加无意义标签,保证层级扁平。
将动画效果应用到position 属性为absolute 或fixed 的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择requestAnimationFrame,详见探讨requestAnimationFrame。
避免使用CSS 表达式,可能会引发回流。
将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe 等标签,浏览器会自动将该节点变为图层。
CSS3 硬件加速(GPU 加速),使用css3 硬件加速,可以让transform、opacity、filters 这些动画不会引起回流重绘。但是对于动画的其它属性,比如background-color 这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
JavaScript
1、避免频繁操作样式,最好一次性重写style 属性,或者将样式列表定义为class并一次性更改class 属性。
2、**避免频繁操作DOM,**创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
3、避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
4、**对具有复杂动画的元素使用绝对定位,**使它脱离文档流,否则会引起父元素及后续元素频繁回流。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值