【性能优化】减少重排重绘

1. 概念

渲染流程.jpg
  • 重排:节点信息计算,即根据渲染树计算每个节点的几何信息(大小及位置)
  • 重绘:渲染绘制,即根据计算好的信息绘制整个页面,渲染出最终的页面
  • 浏览器渲染页面默认采用的是流式布局模型(Flow Based Layout),这一点很重要。

2. 导致重排因素

  • 页面首次渲染
  • 浏览器窗口大小发生改变resize
  • 元素尺寸或位置发生改变
var box = document.querySelector('.box');
//下面每一次操作,在浏览器没有优化的情况下,都会进行一次重排
box.style.width = '100px';
box.style.height = '100px';
box.style.margin = 10px;
box.style.padding = "5px";
重排1.png
重排2.png
//不仅牵扯到位置,还牵扯到BFC,从而进一步影响重排
box.style.position = "absolute";
box.style.top = "100px";
box.style.left = "100px";
box.style.display = "flex";
box.style.overflow = "hidden";
  • 元素内容变化(文字数量或图片大小等等)
  • 元素字体大小变化font-size
  • 添加或者删除可见的DOM元素。
  • 激活CSS伪类(例如::hover
  • 设置style属性
  • 查询某些属性或调用某些方法
//以下属性没有被浏览器优化,减少获取次数
offsetXXX...
clientXXX...
scrollXXX...

//以下方法没有被浏览器优化,减少调用次数
scrollIntoView()
scrollIntoViewIfNeeded()
scrollTo()
getComputedStyle()
getBoundingClientRect()

3. 减少重排

//只进行一次重排
box.style.cssText = 'width: 100px; height: 100px; margin: 30px; padding: 20px; border: 10px solid red';

//或者直接修改class类名
.mybox {
        width: 100px;
        height: 100;
        margin: 30px;
        padding: 20px;
        border: 10px solid red;
}
box.className = 'mybox '

借用其他大佬的总结:

  • 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性
  • 实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局
  • 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
  • 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围

参考文献:
https://blog.csdn.net/cc_together/article/details/105497631
https://zhuanlan.zhihu.com/p/40605154
https://www.cnblogs.com/soyxiaobi/p/9963019.html

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容