什么是重绘和重排

HTML中,每个元素都可以理解成一个盒子,在浏览器解析过程中,会涉及到重排与重绘。

一、什么是重绘(repaint)和重排(reflow)

重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。

重排:当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。

局部范围重排:把dom的宽高之类的几何信息定死,然后在dom内部触发重排,就只会重新渲染该dom内部的元素,而不会影响到外界。

浏览器解析渲染机制如下:

①.解析HTML,生成DOM树,解析CSS,生成CSSOM树

②.将DOM树和CSSOM树结合,生成渲染树(Render Tree)

③.Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)

④.Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素

⑤.Display:将像素发送给GPU,展示在页面上

在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变。

当我们对 DOM 的修改引发了 DOM几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出来。

二、常见的引起重绘的属性

colorborder-stylevisibilitybackgroundtext-decoration
background-imagebackground-positionbackground-repeatoutline-coloroutline
outline-styleborder-radiusbox-shadowbackground-sizeoutline-width

三、常见引起重排属性和方法

widthheightmarginpadding    display
border-widthborderpositionoverflowfont-size
vertical-alignmin-heightclientWidthclientHeightclientTop
clientLeftscrollWidthscrollHeightscrollTop

scrollLeft

getComputedStyle()getBoundingClientRect()scrollIntoViewIfNeeded()伪类:如:hover

四、什么情况下会触发重绘

触发回流时一定会触发重绘,除此之外,例如颜色修改,设置圆角、文本方向修改,阴影修改等。

五、什么情况下会触发回流

回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流,如下面情况:
①.添加或删除可见的DOM元素
②.元素的位置发生变化
③.元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
④.内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
⑤.页面一开始渲染的时候(这避免不了)
⑥.浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

提示:重绘不一定导致重排,但重排一定会导致重绘。

六、浏览器优化机制

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

当你获取布局信息的操作的时候,会强制队列刷新,包括前面讲到的offsetTop等方法都会返回最新的数据。因此浏览器不得不清空队列,触发回流重绘来返回正确的值。

七、重排优化方案有哪些?

一、减少重排的范围
①.尽可能的在DOM树的最末端改变class,重排是不可避免的,但是可以减少其影响,尽可能的在DOM树的最末端改变class,可以限制重排的范围,尽可能少的影响其他节点。

②.不要使用table布局,可能很小的一个小改动会造成整个table的重新布局,在不得已使用table的场合,可以设置table-layout:auto,或者table-layout:fixed,这样可以让table一行一行的渲染,这种做法是为了限制reflow的影响范围。

二、减少重排的次数

①.样式集中改变
不要频繁的操作样式,对于一个静态页面来说,明智且可维护的做法是更改类名,而不是修改样式。对于动态改变的样式来说,相较每次微小修改都直接触及元素,更好的办法是统一在cssText变量中编辑。虽然现在大部分现代浏览器会有flush队列进行渲染队列优化,但是有些老版本的浏览器效率依然低下。

②.分离读写操作
DOM的多个读操作或者写操作,应该放在一起,不要两个读操作之间加入一个写操作
当我们修改了元素的集合属性,导致浏览器触发重排或重绘时,它会把该操作放进渲染队列,等到队列中操作到了一定的数量或者到了一定的时间间隔时,浏览器就会批量执行这些操作。

③.将DOM离线
使用display:none; 一旦我们给元素设置display:none时(只有一次重排重绘),元素便不会再存在在渲染树种,相当于将其从页面上“拿调”,我们之后的操作将不会触发重绘和重排,添加足够多的变更后,通过display属性显示(另一次重排重绘)。通过这种方式即时大量变更也只是触发两次重排,visibility:hidden的元素只对重绘有影响,不影响重排
通过documentFragment创建一个dom碎片,在它上面批量操作dom,操作完成之后,再添加到文档中,这样只会触发一次重排。
复制节点,在副本上工作,然后替换他。

④.使用absolute或fixed脱离文档流
使用绝对定会使的该元素单独成为渲染树中的body的一个子元素,重排开销比较小,不会对其它节点造成太多的影响,当你在这些节点上放置这个元素时,,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。

⑤.优化动画
可以把动画效果应用到position属性为absolute或fixed的元素上,这样对其他元素影响较小。
启用GPU加速GPU硬件加速是指应用GPU的图形性能对浏览器中的一些图形操作交给GPU来完成,GPU专门是为处理图形而设计的,在速度和能耗上更有效率。

  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值