重绘与重排是浏览器渲染的重要动作,对前端性能影响非常大,所以值得多了解一下
什么是重绘与重排?
重绘是一个改变元素外观的行为,例如改变visibility、背景色等属性
重排是浏览器重新计算各个元素的排列位置,需要重新进行布局计算,例如改变元素的宽高、元素内的内容
重绘不会带来重新布局,并不一定伴随重排,但重排一定会导至重绘
哪些操作会引起重排?
(1)改变DOM元素的几何属性
某元素的几何属性发生变化时,会触发子节点、兄弟节点、祖先节点重新计算,也就是所有元素都得重新计算大小、位置,整个页面重新渲染,代价非常大
(2)DOM树的结构变化
例如节点的增减、移动等,也会触发重排
这个影响小于第一种情况,因为DOM树的遍历是从上的下,从左到右的,在这个过程中,当前元素不会影响其前面已经遍历过的元素
例如在body最前面插入一个元素,会导致整个文档的重新渲染,而在其后插入一个元素,则不会影响到前面的元素
(3)获取某些属性
当获取一些属性时,浏览器为取得正确的值也会触发重排,这些属性包括:
offsetTop、offsetLeft、 offsetWidth、offsetHeight
scrollTop、scrollLeft、scrollWidth、scrollHeight
clientTop、clientLeft、clientWidth、clientHeight
getComputedStyle()
如何减小重绘重排的性能代价?
(1)将多次改变样式的操作合并成一次
//bad
var test = document.getElementById('test');
test.style.color = '#000';
test.style.background = '#111';
//good
.test {
background: #111;
color: #000;
}
document.getElementById('test').className = 'test';
(2)适当使用绝对定位
在页面逻辑允许的情况下,可以把position属性设为absolute或fixed
这样此元素就脱离了文档流,它的变化不会影响到其他元素
例如淘宝网首页的轮播广告就使用了绝对定位,轮播需要不断修改节点,就会引起大量重排,使用绝对定位可以提高很多性能
(3)把多次对节点的操作合并为一次操作
//bad
for(var i=0; i<10; i++){
$("#test").append('hi');
}
//good
var frag = document.createDocumentFragment();
var str = '';
for(var i=0; i<10; i++){
str += 'hi';
}
$("#test").appendChild(frag);
(4)临时使用display:none
把要频繁操作的节点先置为隐藏,再对其操作,操作完成后,再显示出来
对隐藏节点的操作是对页面没有任何影响的,只是隐藏和显示这两个动作触发重排
(5)缓存属性值
在需要经常取上面提到的那些引起浏览器重排的属性值时,要缓存到变量
//bad
var a = document.body.scrollTop + 1;
var b = document.body.scrollTop + 2;
//good
var top = document.body.scrollTop;
var a = top + 1;
var b = top + 2;
标签:浏览器,元素,重绘,var,重排,test,节点 来源: https://blog.51cto.com/u_15127579/2727116
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。