浏览器渲染引擎工作时,会先解析HTML然后生成DOM树,与此同时,渲染引擎也会用CSS解析器解析CSS文档构建CSSOM树。接下来,DOM树和CSSOM树关联起来构成渲染树(RenderTree)然后浏览器按照渲染树进行布局(Layout),最后一步通过绘制显示出整个页面。
重绘和重排的区别:
- 重绘:CSS 样式改变(例如:visibility,背景色的改变),使浏览器需要根据新的属性进行绘制。
- 重排:我们对DOM的修改引发了DOM几何元素的变化,渲染树需要重新计算,重新生成布局,重新排列元素。
单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分。比如改变元素高度,这个元素乃至周边dom都需要重新绘制。
即:重绘不一定导致重排,但重排一定会导致重绘
引起重排的的情况
当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排
引起重排的几个原因
- 页面初始渲染,这是开销最大的一次重排
- 添加/删除可见的DOM元素
- 改变元素位置
- 改变元素尺寸,比如边距、填充、边框、宽度和高度等
- 改变元素内容,比如文字数量,图片大小元素字体大小等
- 改变浏览器窗口尺寸,比如resize事件发生时
- 激活CSS伪类(例如::hover)
- 设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow
- 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等。原理是一样的,都为求一个“即时性”和“准确性”。
重排影响的范围
- 全局范围:从根节点html开始对整个渲染树进行重新布局。
-
局部范围:对渲染树的某部分或某一个渲染对象进行重新布局
把一个dom的宽高之类的几何信息定死,然后在dom内部触发重排,就只会重新渲染该dom内部的元素,而不会影响到外界。(例如position为absolut和fixed)
重排优化建议
- 减少重排范围,以局部布局的形式组织html结构,尽可能小的影响重排的范围。
- 减少重排次数
- 样式集中改变
// bad var left = 10; var top = 10; el.style.left = left + "px"; el.style.top = top + "px"; // 当top和left的值是动态计算而成 时... // better el.style.cssText += "; left: " + left + "px; top: " + top + "px;"; // better el.className += " className";
- 分离读写操作
- 将 DOM 离线,(使用 display:none)
- 使用 absolute 或 fixed 脱离文档流
- 优化动画
网友评论