- 浏览器使用HTTP协议或者HTTPS协议向服务端请求页面
- 将请求回来的HTML代码解析并构建DOM树
浏览器的渲染过程:
- 解析HTML,构建DOM tree
- 解析CSS(CSS 解析是把 CSS 规则应用到 DOM 树上,为 DOM 结构添加显示相关属性的过程),构建CSSOM tree
- 合并DOM tree和CSSOM tree,生成render tree
- 布局(layout/reflow),计算各元素尺寸、位置
- 绘制(paint/repaint),绘制页面像素信息
- 浏览器将各层的信息发送给GPU,GPU将各层合成,显示在屏幕上
解析html 为DOM 树 :
1)HTML字节流解码变为字符流。根据不同编码方式,如UTF-8 GBK来解码
2)词法分析:将字符流解析为一个个词语
3)语法分析:通过不同标签,生成node节点
4)构建DOM树:将node节点组织成DOM树
关于Repaint 和 Reflow

repaint重绘:
如果只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,则只会引起浏览器 repaint,repaint 的速度明显快于 reflow
reflow回流:
当某个部分发生了变化影响了布局,需要倒回去重新渲染, 该过程称为reflow(回流)。比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距大小等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染,所以reflow的代价是比较大的
reflow一定引起repaint,而repaint不一定要reflow
在哪些情况下会导致reflow发生:
-
改变窗囗大小
-
改变文字大小
-
添加/删除样式表
-
内容的改变,如用户在输入框中输入
-
激活伪类,如:hover
-
操作class属性
-
通过脚本操作DOM
-
设置style属性
优化方法,尽量避免reflow:
-
尽可能限制reflow的影响范围,修改DOM层级较低的结点。不要通过父级元素影响子元素样式。最好直接加在子元素上。改变子元素样式尽可能不要影响父元素和兄弟元素的尺寸。
-
不要一条一条的修改DOM的style,最好通过设置class的方式。 避免触发多次reflow和repaint。
-
经常reflow的元素,如动画,可将position设为fixed或absolute,使其脱离文档流,不影响其它元素的布局。
-
权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
-
尽量不使用tables布局。tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
-
避免使用css expression(每次都会重新计算)。
-
减少不必要的 DOM 层级(DOM depth)。改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面。
-
避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。
-
尽量不要频繁的增加、修改、删除元素,可以先把DOM节点抽离到内存中进行复杂的操作然后再display到页面上。(display:none的节点不会被加入render tree,而visibility:hidden会;display:none会触发reflow,而visibility:hidden只会触发repaint,因为layout没有变化)。
网友评论