重绘的场景
一个元素的外观被改变,比如(背景颜色、字体颜色、边框颜色等)
重排(回流)的场景
1.新增或者删除Dom元素
2.元素的位置发生改变
3.元素的尺寸,位置发生改变
4.页面的初始化渲染
5.浏览器的尺寸收缩
6.调用元素的属性,浏览器为取得正确的值也会触发重排,它会导致队列刷新。
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop、
offsetLeft`scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
页面性能优化思路
1.能重绘的尽量补重排
2.能少重排的就不多重排
3.能小区域就不大区域的排
4.避免无效重排
5.利用GPU资源
1.分离读写操作
div.style.left = '10px';
div.style.top = '10px';
// 由于读取属性方法会触发重排,尽量获取代码写在一起,可避免多次重排
console.log(div.offsetLeft);
console.log(div.offsetTop);
2.样式集中改变
// bad
var left = 10;
var top = 10;
el.style.left = left + 'px';
el.style.top = top + 'px';
// good
el.className = 'className'
// good
el.style.cssText = `left:${left}px;top:${top}px;`
3.缓存布局信息
// bad 调用offset系列方法会强制刷新,触发两次重排
div.style.left = (div.offsetLeft + 10) + 'px';
div.style.right= (div.offsetRight + 10) + 'px';
// good 缓存布局信息,触发一次重排
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = (curLeft + 10) +'px'
div.style.top = (curTop + 10) +'px'
4.离线改变Dom
// 修改之前隐藏Dom
dom.display = 'none'
// 修改之后在显示Dom
dom.displaye = 'block'
5.通过DocumentFragment创建一个dom碎片,在它上面批量操作Dom之后,再添加到文档之中,这样就只会触发一次重排
6.position属性设置为absolute或者fixed,能做到小区域重排
7.优化动画,GPU会对这些属性加速:使用css3转换(transitions)、css3 3D变换(transforms)
以上就是我对DOM的重排与重绘的理解,如果文章由于我学识浅薄,导致您发现有严重谬误的地方,请一定在评论中指出,我会在第一时间修正我的文章,以避免误人子弟。