重排、重绘--性能优化问题

本文探讨了网页渲染中的重排(回流)与重绘概念,强调减少重排以优化性能。重排发生在元素尺寸、位置改变时,重绘则涉及元素外观变化。引起重排的因素包括页面初始化、DOM操作、浏览器窗口尺寸变化等。减少重排的策略包括避免table布局、使用绝对定位、批量修改样式、分离读写操作、DOM离线操作等。同时,利用CSS3动画和GPU加速也能有效提升性能。
摘要由CSDN通过智能技术生成
	重绘:某些元素的外观被改变,例如:元素的填充颜色
	重排(回流):重新生成布局,重新排列元素。
  1. 减少重排、重绘优化性能,其中减少重排尤为重要。重新绘制受到此次重排影响的部分,比如改变元素高度,这个元素乃至周边dom都需要重新绘制。重绘不一定导致重排,但重排一定会导致重绘。

  2. 引起重排的原因(掘金+简书的搬运工)
    a. 页面初始渲染,这是开销最大的一次重排
    b. 添加/删除可见的DOM元素
    c. 改变元素位置
    d. 改变元素尺寸,比如边距、填充、边框、宽度和高度等
    e. 改变元素内容,比如文字数量,图片大小等
    f. 改变元素字体大小
    g. 改变浏览器窗口尺寸,比如resize事件发生时激活CSS伪类(例如::hover)
    h. 设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow
    i. 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等,除此之外,当我们调用 getComputedStyle方法,或者IE里的 currentStyle 时,也会触发重排,原理是一样的,都为求一个“即时性”和“准确性”。

  3. 减少重绘的方法:减少重排(c-i)+减少重排范围(a-b)
    a. 尽可能在低层级的DOM节点上,简言之如果想要改变某元素的样式,class就不要加在父元素上。
    b. 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
    c. 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性
    d. 使用绝对定位会使的该元素单独成为渲染树中 body 的一个子元素,重排开销比较小,不会对其它节点造成太多影响。当你在这些节点上放置这个元素时,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。
    e. 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
    f. 不要频繁的操作样式,对于一个静态页面来说,明智且可维护的做法是更改类名而不是修改样式,对于动态改变的样式来说,相较每次微小修改都直接触及元素,更好的办法是统一在 cssText 变量中编辑。
    g. 分离读写操作

     	// bad 强制刷新 触发四次重排+重绘
     	div.style.left = div.offsetLeft + 1 + 'px';
     	div.style.top = div.offsetTop + 1 + 'px';
     	div.style.right = div.offsetRight + 1 + 'px';
     	div.style.bottom = div.offsetBottom + 1 + 'px';
     	// good 缓存布局信息 相当于读写分离 触发一次重排+重绘
     	var curLeft = div.offsetLeft;
     	var curTop = div.offsetTop;
     	var curRight = div.offsetRight;
     	var curBottom = div.offsetBottom;
     	
     	div.style.left = curLeft + 1 + 'px';
     	div.style.top = curTop + 1 + 'px';
     	div.style.right = curRight + 1 + 'px';
     	div.style.bottom = curBottom + 1 + 'px';
    

    h. DOM离线,不在当前dom树中进行操作。(1)使用 display:none,一旦我们给元素设置 display:none 时(只有一次重排重绘),元素便不会再存在在渲染树中,相当于将其从页面上“拿掉”,我们之后的操作将不会触发重排和重绘,添加足够多的变更后,通过 display属性显示(另一次重排重绘)。通过这种方式即使大量变更也只触发两次重排。另外,visibility : hidden 的元素只对重绘有影响,不影响重排。(2)通过 documentFragment 创建一个 dom 碎片,在它上面批量操作 dom,操作完成之后,再添加到文档中,这样只会触发一次重排。(3)复制节点,在副本上工作,然后替换它!
    i. 动画优化。(1)可以把动画效果应用到 position属性为 absolute 或 fixed 的元素上,这样对其他元素影响较小。(2)动画效果还应牺牲一些平滑,来换取速度,这中间的度自己衡量:比如实现一个动画,以1个像素为单位移动这样最平滑,但是Layout就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多.(3)启用GPU加速.GPU 硬件加速是指应用 GPU 的图形性能对浏览器中的一些图形操作交给 GPU 来完成,因为 GPU 是专门为处理图形而设计,所以它在速度和能耗上更有效率。GPU 加速通常包括以下几个部分:Canvas2D,布局合成, CSS3转换(transitions),CSS3 3D变换(transforms),WebGL和视频(video)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值