重绘(Repaint)和回流(Reflow)(重排),以及如何优化?

1、浏览器渲染机制

  1. 浏览器采用流式布局模型;
  2. 浏览器会把HTML解析成DOM树,解析css构建render树(将css解析成树形的数据结构,然后结合DOM合并成render树)
  3. 有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制带页面上
  4. 由于浏览器使用流式布局,对RenderTree的计算同城只需要遍历一次就可以完成,但table及内部元素除外,他们可能需要多次计算,通常需要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一。

2、重绘

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

3、回流(重排)

回流就是布局或者集合属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(整个页面)的布局更新,一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。因为其在DOM中回流元素之后,大部分回流将导致页面的重新渲染,回流必定会发生重绘,重绘不一定会引发回流。

下面这些操作会导致回流:

  1. 页面的首次渲染
  2. 浏览器的窗口大小发生变化
  3. 元素的内容发生变化
  4. 激活css伪类
  5. 查询某些属性或者调用某些方法
  6. 添加或者删除可见的DOM元素

4、浏览器优化

现在浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新才会清空队列,但是当你获取布局信息的时候,比如改变元素的高度,元素的位置,导致浏览器不得不重新计算与元素的几何属性,队列中可能会有影响这些属性或方法值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值并重新构建渲染树。

主要包括以下属性或方法:

  1. offsetTop、offsetLeft、offsetWidth、offsetHeight
  2. scrollTop、scrollLeft、scrollWidth、scrollHeight
  3. clientTop、clientTlLeft、clientTWidth、clientTHeight
  4. width、height
  5. getComputedStyle()
  6. getBoundingClientRect()

所以我们应该避免频繁的使用上述的属性,它们斗湖强制渲染刷新队列

5、减少重绘与回流

  1. css
  • 使用tarnsform替代top
  • 使visibility替换dispaly:none。因为前者只会引起重绘,后者会引起回流。
  • 避免使用table布局,可能很小的一个改动会造成整个table的重新布局
  • 尽可能在DOM树的最末端改变class,回流是不可避免的,但是可以减少其影响,尽可能在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。
  • 避免设置多层内联样式,css选中符从右往左匹配查找,避免节点层级过多,保证层级扁平。
  • 将动画效果应用到position属性为absolute或者fixed元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选中requestAnimationFrame.
  • 避免使用css表达式,可能会引起回流
  • css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘。但是对于动画的其他属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提高这些动画的性能
  1. js
  • 避免频繁操作样式,做好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
  • 避免频繁操作DOM;可以创建一个documentFragment,在它上面应用所有DOM操作,最后把它添加到文档中
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值