由于浏览器的加载、解析、渲染是一个较为复杂的过程,本文将这三部分拆解开来,仅对浏览器渲染部分进行讲解。
第一阶段:构建DOM树
进入正题,当网页输入URL时候,浏览器调用相应的资源加载器。
加载器依赖网页模块建立连接,发起请求并接受回复。
浏览器接收到各种网页或者资源的数据,其中某些资源可能是同步的也可能是异步的。
网页被加载给html解释器变为一系列的词语(token)。
解析器根据词语构建节点node,形成DOM树。
如果节点是js代码的话则调用js引擎解释执行并且阻塞DOM树的构建与渲染(js代码可能会修改DOM树的结构)。
如果节点需要依赖其他资源,例如图片,CSS,视频等,调用资源加载器加载他们,此过程为异步,不会阻碍当前DOM树的构建(CSS加载不会阻碍DOM树的构建,但会阻塞渲染)。对于js资源的加载,则会阻塞DOM树的构建和渲染,除非设置了script标签的异步属性。特别的,加载资源是由单独的下载线程进行异步加载,浏览器会并行加载,不过具体并行最大加载数量是有一定限制的。
第二阶段:构建CSS规则树
与DOM树的构建基本相同,都是要经过过Bytes→Characters→Tokens→Nodes→Objectmodel这个过程。但值得注意的是,CSS是一种渲染阻塞资源(render blocking resource),它需要完全被解析完毕后才能进入生成渲染树的环节。
第三阶段:CSS与DOM树生成Render树
1.DOM树从根节点开始遍历可见节点(script,meta,head等除外,visibility:hidden;opacity:0这种仍占据空间的节点除外),浏览器会创建RenderObject对象,该对象保存了为绘制DOM节点所必须的各种信息,例如样式布局信息,经过浏览器处理后RenderObject对象知道如何绘制自己。
2.RenderObject对象构成一颗基于DOM树的新树,为了布局计算和渲染等机制建立的一种新的内部表示。如果DOM树中添加了新的节点,浏览器也需要创建相应的RenderObject对象。
第四阶段:生成布局(Generating the Layout)
有了各个节点的样式信息和属性,但不知道各个节点的确切位置和大小,所以要通过布局将样式信息和属性转化为实际可视窗口的相对大小和位置。可视窗口大小是由meta标签的name属性为viewport的内容设置所决定的,如果缺少这个标签,默认的视口大小为980px。
第五阶段:绘制(Painting)
最后,页面上可见的内容就会通过GPU转化为屏幕上的像素点。绘制过程所需要花费的时间取决于DOM的大小以及元素的CSS样式。有些样式比较耗时,比如一个复杂的渐变背景色比简单的单色背景色需要更多的渲染时间。
第六阶段:回流(reflow)与重绘(repaint)
当元素的内容、结构、位置、或尺寸发生了变化,需要重新计算元素样式(reflow)。
当元素的样式(背景色、边框颜色、文字颜色等)发生变化,需要重新绘制元素(repaint)。
需要注意的是当出发reflow时都会触发repaint,但是repaint不一定触发reflow,即重绘可以单独触发。
领取专属 10元无门槛券
私享最新 技术干货