浏览器大家都不陌生了,可以说没有浏览器,网络就是个迷宫,而不是个你接触到的精彩的网络世界。我们都知道,当我们需要访问网络上的一个站点的时候,需要打开浏览器,在浏览器上输入域名,然后点击回车,网站的内容就会呈现在你的眼前。正常情况下,这个过程很快,尤其现在网络提速的情况下,但是你却不知道就这短短几秒钟内,发生了什么?
简单来说,你在浏览器看到的是自己电脑(本地的),但是这个东西在你没访问之前是网站的,浏览器的工作就是找到你要看的网站,然后把它的内容拿到你电脑的浏览器,然后你的浏览器再整理打扮一下,然后在浏览器窗口展示给你。概括来说,浏览器就是“找”、“拿”、“整理打扮”。其中“找”和“拿”涉及到DNS寻址以及网络方面的知识,这里就不敞开介绍,这里主要介绍最后一个过程,就是浏览器将获取的资源进行“整理打扮”并展示给用户的过程。需要说明的是,网络请求的网站资源一般都是二进制流传过来的HTML、CSS、JS文件,以及图片、PDF以及其他类型的文件。
渲染(Rending)主流程: 将获取的HTML文档解析生成DOM树,然后生成渲染树,布局渲染树,最后是绘制渲染树,绘制的结果就是将内容(HTML文字字符)、样式(CSS)、动作(JS)和其他资源(图片、PDF文件等)作为浏览器窗口看到的页面。
主要过程
而不同的浏览器内核,在这个主流程下的具体步骤,实现方法略微有区别,但主要步骤基本一致。
解析(Parsing)与生成DOM树
解析文档是将获取的文档按照一定的规则转化成符合规范的结构,也就是浏览器能够识别和处理的结构,解析的输入是HTML,CSS,JS文档等,输出通常是代表了文档结构的DOM节点树,也称语法树。具体来说,解析包括两个子过程,词法解析和语法解析。词法解析器将文档中的内容分解成有效标记,并处理一些无关的字符,解析器再根据一定的语法规则,生成解析树(DOM树)。
解析过程
HTML 解析器的工作就是是将 HTML 标记解析成解析树。
生成渲染树
在生成解析树的同时,还会构建渲染树。渲染树由可视化元素(标记)按照一定的顺序组成。渲染树的工作是规定顺序以保证正确的将页面绘制出来。不同的浏览器内核生成渲染书的方法不一样,Webkit内核将解析样式和创建渲染树的过程称为“附加”,每隔DOM节点都有一个“attach”方法。Gecko内核(火狐)则将渲染树中的元素称为”框架“(Frame)。处理html和body标记就会变为生成渲染树的根节点。这个根节点呈现对象类似于 CSS 规范中所说的容器 block,这是外层的 block,包含了其他所有 block。它的尺寸就是视口(viewport),即浏览器窗口显示区域的尺寸。
渲染树
需要注意的是,DOM中的节点和渲染对象并不是一一对应的关系,比如一些不可见的元素如样式中display值为none的元素,不是给用户阅读的节点等就不会被生成到渲染树中。
布局渲染树
当生成了DOM树和渲染树,树的节点并没有位置和大小的信息,完全是杂乱无章的摆在那里。而计算节点位置和大小的过程就是布局的过程,称为layout 或者reflow.HTML文档是基于流的布局模型,也称文档流,其布局顺序为自然顺序,自上而下,从左向右。再进行样式的计算时,使用规则树计算样式,确定有限顺序和最终结果。
绘制渲染树
在增量的绘制过程中,一些渲染对象以不影响整棵树的方式改变,改变的渲染对象使其在屏幕上的矩形区域失效,这将导致操作系统将其看作dirty区域,并产生一个paint事件,操作系统很巧妙的处理这个过程,并将多个区域合并为一个。Chrome中,这个过程更复杂些,因为渲染对象在不同的进程中,而不是在主进程中。Chrome在一定程度上模拟操作系统的行为,表现为监听事件并派发消息给渲染根,在树中查找到相关的渲染对象,重绘这个对象(往往还包括它的children)。css2定义了绘制过程的顺序
这个就是元素压入堆栈的顺序,这个顺序影响着绘制,堆栈从后向前进行绘制。一个块渲染对象的堆栈顺序是:
1. 背景色-》2. 背景图-》3. border-》4. children-》5. outline
所有的渲染对象都有一个layout或reflow方法,每个渲染对象调用需要布局的children的layout方法。
以上四个流程是浏览器工作的主要原理,每个过程又包含非常复杂的子流程。上述一个完整的流程走完,只是表示页面完成一次加载,但是现实情况是,页面并不是一次可以加载完,而是不同的变化之中。基于性能和效率的考虑,还设计到浏览器重绘,线程,事件等一些列知识点。总之,两三秒打开页面的背后,远没有你看见的这么简单。复杂的背后交给前端,简单的结果呈现给用户,这也是产品的要义。
为梦想而coding
领取专属 10元无门槛券
私享最新 技术干货