浅析浏览器的渲染过程
浏览器渲染过程
构建DOM树:浏览器接收到服务器响应来的HTML文档后,会遍历文档节点,生成DOM树。
构建CSS规则树:浏览器解析CSS文件并生成CSSOM,css规则树。
构建渲染树(Render):通过DOM树和CSS规则树,浏览器就可以通过它两构建渲染树(浏览器会先从DOM树的根节点开始遍历每个可见节点,然后对每个可见节点找到适配的CSS样式规则并应用)
渲染树布局:浏览器就可以通过这些样式信息来确定每个节点对象在页面上的确切大小和位置,布局阶段的输出就是我们常说的盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小
渲染树绘制:在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()
方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的
回流和重绘(reflow和repaint)
回流
当浏览器发现布局发生了变化,这个时候就需要倒回去重新渲染,这个回退的过程叫reflow
reflow
会从html
这个root frame
开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树。reflow
几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会reflow
哪一部分的代码,因为他们会相互影响。- 页面第一次渲染(初始化)
- DOM树变化(如:增删节点)
- Render树变化(如:
padding
改变) - 浏览器窗口
resize
- 获取元素的某些属性
重绘
repaint
则是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。
背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)
减少reflow、repaint触发次数
- 用
transform
做形变和位移可以减少reflow
- 避免逐个修改节点样式,尽量一次性修改
- 使用
DocumentFragment
将需要多次修改的DOM元素缓存,最后一次性append
到真实DOM中渲染 - 可以将需要多次修改的DOM元素设置
display:none
,操作完再显示。(因为隐藏元素不在render
树内,因此修改隐藏元素不会触发回流重绘) - 避免多次读取某些属性
- 通过绝对位移将复杂的节点元素脱离文档流,形成新的Render Layer,降低回流成本