重排和重绘

1、重排一定会触发重绘,但是重绘不一定会触发重排

重排是什么?

当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),使得部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素,并将其安放在界面中的正确位置,这个过程叫做重排。

什么情况下会发生重排?

1.页面初始渲染,这是开销最大的一次重排
2.添加/删除可见的DOM元素
3.改变元素位置
4.改变元素尺寸,比如边距(margin)、填充(padding)、边框(border)、宽度和高度等
5.改变元素内容,比如文字数量,图片大小等
6.改变元素字体大小
7.改变浏览器窗口尺寸,比如resize事件发生时
8.激活CSS伪类(例如::hover)
9.通过display:none隐藏一个DOM节点
10.给页面中的DOM节点添加动画

重绘是什么?

由于节点的样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变,但没有改变布局。除此之外,重排也必然会触发重绘。

除了重排触发重绘,下面情况会发生重绘:

1.改变颜色
2.通过visibility:hidden隐藏元素
3.改变border-style
4.添加圆角、阴影

2、重排重绘的代价究竟有多大呐?

咱们可以举一个“过桥”的例子,细心的你可能会发现了,千倍的时间差并不是由于“过桥”一手造成的,每次“过桥”其实都伴随着重排和重绘,而耗能的绝大部分也正是在这里!

代码展示

// console.time和console.timeEnd这两个方法可以用来让WEB开发人员测量一个javascript脚本程序执行消耗的时间。
// console.time方法是开始计算时间,console.timeEnd是停止计时,输出脚本执行的时间。
​
var times = 1000
// 情况1  每次过桥 + 重绘 + 重排
console.time(1);
for(var i = 0; i < times;i++){
    document.getElementById("myDiv1").innerHTML += "z"
}
console.timeEnd(1)
​
// 情况2 只过桥
console.time(2);
var str = ''
for(var i = 0; i < times;i++){
    str += "z"
}
document.getElementById("myDiv2").innerHTML += str
console.timeEnd(2)

3、如何避免重排重绘

1.减少重排的范围
2.尽量以局部布局的形式组织html结构,尽可能小的影响重排的范围。比如触发BFC,改变BFC内部的元素,不会影响到外部。

4、减少重排重绘的次数

  1. 集中改变样式 通过改变class的方式来集中改变样式

  2. 将 DOM 离线 1)使用display:none 一旦我们给元素设置 display:none 时(只有一次重排重绘),元素便不会再存在在渲染树中,相当于将其从页面上“拿掉”,我们之后的操作将不会触发重排和重绘,添加足够多的变更后,通过 display:block属性显示(另一次重排重绘)。通过这种方式即使大量变更也只触发两次重排重绘。 2)使用documentFragment document.createDocumentFragment创建一个游离于DOM树之外的节点,然后在此节点上批量操作,最后插入DOM树中,只触发一次重排重绘

  3. 提升为合成层 1)合成层的位图,会将于GPU合成,比CPU快 2)当需要重排重绘时,只影响本身,不影响其他层 3)对于transform和opacity,不会触发重排和重绘,只会触发合成 4)如何提升为合成层:css的will-change属性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值