第13题:谈谈什么是回流会重绘?怎么优化

前面的话

这篇文章从回流会重绘的角度谈谈如何优化浏览器性能

什么是回流与重绘?
回流

在浏览器渲染过程中,生成渲染树之后,根据渲染树对可见DOM节点进行布局,还需要进行计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流。

重绘:

根据渲染树以及布局阶段,知道了DOM节点的样式与位置大小信息,那么就可以将渲染树的每一个节点转换为屏幕上的实际像素,这个阶段就叫重绘。

何时发生回流与重绘?

回流阶段主要是计算节点的位置与大小,会重新布局。重绘是根据DOM节点的样式与布局阶段再去绘制每个节点。 那么当页面布局和节点的位置大小信息发生变化时,就会发生回流。

回流:

  • 添加或删除DOM,或元素的位置、尺寸发生变化
  • 内容发生变化,比如文本变化或图片被另外一个不同的尺寸图片所代替
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

重绘:

  • 改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。

[注意]回流必定会发生重绘,重绘不一定会引发回流。回流所需得成本比重绘高得多,改变父节点里得子节点很可能会导致父节点得一系列回流。

浏览器的优化机制

由于每次回流重绘都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放到队列里,直到过了一段时间或者达到一个阈值,才会清空队列。

但是,当你获取布局信息的操作时,会强制刷新队列。比如访问一下属性:

  • offset家族: offsetTop、offsetLeft、offsetWidth、offsetHeight
  • scroll家族:scrollTop、scrollLeft、scrollWidth、scrollHeight
  • client家族:clientTop、clientLeft、clientWidth、clientHeight
  • getComputedStyle()
  • getBoundingClientRect

使用以上属性或方法都要返回最新的布局信息,浏览器不得不清空队列,触发回流重绘。所以在修改样式时, 最好避免出现上面的属性方法。如果要是用,最好先把值缓存起来。

减少重绘与回流
css方面:
  • 使用transform代替 top, left ,margin-top, margin-left… 这些位移属性
    transform: translateY(200px)代替
    position: relative;
    top: 200px;
    
    当一段时间改变元素的位置时,使用top会有很明显回流时间,使用transform页面的回流会直接没有,如果频繁改变位置两者的效果十分明显。
  • 使用visibility代替display: none ,前者只会引起重绘,后者引发回流。有必要时使用opacity(透明度)来代替display: none
  • 避免使用table布局: 可能很小的改动会造成整个table的重新布局
  • 让多次重排的元素脱离文档流比如动画,使用 position 属性的 fixed 值或 absolute 值
  • 避免设置多层内联样式,降低样式选择器的复杂度。CSS 选择符从右往左匹配查找,因避免节点层级过多。
  • 将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流。
  • CSS3 硬件加速(GPU加速),使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。
  • 使用flexbox替代老的布局模型:老的布局模型以相对/绝对/浮动的方式将元素定位到屏幕上,而Floxbox布局模型用流式布局的方式将元素定位到屏幕上。
javaScript
  • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中
  • 避免连续的强制的同步布局发生:不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight… 这些。
  • 避免频繁读取会引发回流/重绘的属性(offsetWidth, offsetHeight等),如果确实需要多次使用,就用一个变量缓存起来。
  • 动画实现使用requestAnimationFrame:保证callback函数在每帧动画开始的时候执行
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值