浏览器下载完页面中的所有组件——HTML
标记、JavaScript
、CSS
、images
————之后会解析并生成两个内部数据结构
DOM Tree
表示页面结构
Render Tree
表示DOM节点如何显示
浏览器的渲染过程
1、处理HTML
标记并构造DOM
树
2、处理CSS
标记并构造CSSOM
树
3、将DOM
与CSSOM
合并成一个渲染树
4、根据渲染树(Render Tree)来布局,以计算每个节点的几何信息
5、将各个节点绘制到屏幕
生成Render Tree渲染树
触发重排(Reflow)和重绘(Repaint)
DOM
元素的添加、修改(内容)、删除(Reflow + Repaint)
仅修改DOM
元素的字体颜色(只有Repaint,因为不需要调整布局)
重绘(Repaints)
当页面中DOM元素样式以及可见性
visibility
发生改变的时候,但是并不影响布局(eg:color
、outline
、visibility
、background-color
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘(Repaints)
重排(Reflows)
当
Render Tree
中涉及到部分或整个页面的布局, 因元素的尺寸(Size)、布局(Layout)、隐藏(Display)等改变而需要重新构建导致了其所有子元素以及DOM
中紧随其后的祖先元素的随后的浏览器重新渲染的过程称为 重排(Reflows)
哪些操作会导致浏览器的重排(Reflows)呢?
- 添加或删除可见的
DOM
元素 - 元素位置改变
- 元素尺寸改变(包括:
margin
(外边距)、padding
(内边距)、border-width
(边框厚度)、width
(宽度)、height
(高度)等属性改变)。 - 页面渲染器初始化
- 调整浏览器窗口大小(Resizing the window)
- 改变字体(Changing the font)
- 增加或移除样式表(Adding or removing a stylesheet)
- 内容变化,比如用户在
input
框中输入文字(Content changes, such as a user typing text in an input box),文本改变成图片被另一个不同尺寸的图片替代 - 激活
CSS
伪类,比如::hover
(IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling)) - 操作
class
属性(Manipulating the class attribute) - 脚本操作DOM(A script manipulating the DOM)
- 计算
offsetWidth
和offsetHeight
属性(Calculating offsetWidth and offsetHeight) - 设置 Style 属性的值 (Setting a property of the style attribute)
总结:
重排必将引起重绘,重绘不一定会引起重排。
性能影响
有时即使仅仅重排(Reflow)一个单一的元素,它的父元素以及任何跟随它的元素也会产生重排(Reflow)
现代浏览器会对频繁的重排(Reflow)或重绘(Repaints)进行优化:
由于每次重排都会产生计算消耗,大多数浏览器可通过队列化修改并批量执行来优化重排过程。
可通过以下方法强制刷新队列并要求计划任务立刻执行。获取布局信息的操作会导致队列刷新,比如以下方法:
offsetTop
、offsetLeft
、offsetWidth
、offsetHeight
scrollTop
、scrollLeft
、scrollWidth
、scrollHeight
clientTop
、clientLeft
、clientWidth
、clientHeight
scrollIntoView()
、scrollIntoViewIfNeeded()
、getComputedStyle()
getBoundingClientRect()
scrollTo()
因为队列中可能会有影响到这些属性或方法返回值的操作,即使你希望获取的信息与队列中操作引发的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。