页面卡顿时,往往是因为过多操作DOM导致的;如果引起浏览器的重绘(repaint)、重排(reflow),则更会影响浏览器的性能,repaint、reflow会消耗很多资源;
在开发中应该尽量减少对DOM的操作,从而减少DOM元素repaint,reflow的几率;如果要了解重绘、重排,首先要了解浏览器加载文档的过程;
理解了这个过程,基本上就掌握了浏览器原理,减少DOM操作、性能优化的技术;
一, 浏览器加载网页的过程
1.1 浏览器下载、加载文档
1.2 浏览器解析HTML构建DOM树;解析CSS规则构建css规则树;
1.3 浏览器在解析js时,可能会修改DOM树,css规则树;
1.4 之后,浏览器根据DOM树、css规则树构建 渲染树;(在构建渲染树的过程中,css根据规则匹配HTML;同时每一个元素上都包括大小、边距、颜色等样式属性;)
1.5 最后,浏览器根据这个渲染树,将元素绘制在页面上;
简而言之, DOM树 + CSS规则树 ===> 构建渲染树 ===> 浏览器根据渲染树,绘制在页面上;
重绘(repaint) : 页面某些部分需要重新绘制,比如某些元素修改了颜色或者背景色,元素位置、尺寸没有改变;
重排(reflow): 页面元素位置、尺寸发生变化时,浏览器需要重新计算渲染树,导致渲染树的一部分或者全部需要变化;渲染树构建好后,浏览器重新根据渲染树绘制受影响的元素;
因此,重排比重绘更影响性能;重绘不可怕,可怕的是重排reflow,因为会重新构建渲染树等;
二,哪些操作会导致重排?
2.1 页面初始渲染
2.2 添加、删除DOM元素
2.3 改变浏览器窗口大小
2.4 元素的位置、尺寸、内容等发生改变
三,如何减少重排?
3.1 将多次修改样式的操作合并成一次
var ele = document.querySelector('#btn'); ele.style.color = '#003355'; ele.style.backgroundColor = '#333333'; ele.style.fontSize = '16px' // 合并成一次 // a.css .btnStyle{ color:'', background-color:'' font-size:'' } ele.className='btnStyle'
3.2 使用事件委托技术
使用事件委托减少对DOM的操作
3.3 一次性生成DOM节点,不要一个个添加,要一次性生成完,然后添加;
3.4 属性为display:none的元素不会添加到渲染树上;脱离文档流的元素,不会在渲染树上
在面试中,经常测试的一道题目:如何实现表格的排序?
如果能够考虑到浏览器的重排、重绘,以及如何减少重排重绘,方案会更令人满意。
参考: