现代浏览器的背后的工作原理


现代浏览器背后的机制

主要介绍从地址输入一个URL到浏览器呈现出最终内容,都经过了哪些步骤。

首先来说,在这个过程中会涉及到多个模块的工作。

  • 浏览器主模块
  • render渲染
  • UI
  • 网络
  • 存储
  • JS引擎

第一个阶段

在地址栏开始输入URL到浏览器发出网络请求之前,都是浏览器的主模块在工作。浏览器的主模块主要负责浏览器中地址栏、书签、前进/后退按钮等除了用户内容展示区域以外的部分。在URL输入完成后,??browser会先检查缓存信息,如果有效则直接从缓存处获取数据;否则通知网络模块去服务端查询数据。

第二个阶段

网络模块首先会进行DNS查询,对URL进行lookup查询(先查询本地hosts文件,如果没有则向网络服务商查询知道根域名解析服务器)。获取IP地址后,跟服务端建立HTTP连接,然后开始取数据。

第三个阶段

解析数据,从服务端获取到HTML数据(通常情况下是这样,其它格式属于浏览器的扩展功能,暂且不讨论)后,交给render渲染模块进行解析。渲染引擎解析分为三种类型:

  • HTML代码解析,生成DOM tree
  • CSS代码解析,生成style tree
  • JavaScript代码解析,执行相应的操作

第三个阶段中的第一部分

html/css 代码的解析可以同步进行。

浏览器解析HTML/CSS代码是词法分析和解析的过程。生成的DOM tree上, 每一个节点可以看作是对应的一个标签,这个标签下的子元素则对应dom tree中的子节点。

在解析css代码时候,会不断的把解析出来的style tree附加到dom tree上。

dom tree 和 style tree合并后会形成 render tree。 UI模块就是根据render tree进行内容绘制呈现给用户。

第三阶段中的第二部分

在解析HTML代码的过程中,如果遇到script标签,则去解析JS代码。

如果script标签存在src属性值,引用了外部代码;浏览器则会先通过网络获取对应的代码到本地然后执行。否则,直接执行script内部的代码。在这个过程中,对DOM到解析是暂停的。因为在JS代码中,可能会存在DOM操作的情况,如果此时解析DOM到进程仍在进行,至于解析到哪一步谁也无法预知,因此DOM操作就存在了一定的不可预知性。

不过此处存在 scrpte标签带有 defer 属性的情况。如果存在defer属性,且script引用了外部脚本,则该script标签下的代码会等到DOMContentLoaded后再执行。

<script defer src="./index.js"> </script>
<p id="defered">defer</p>

index.js 文件内容

console.log(document.getElementById('defered'));

在整个文档解析的过程中,Dom tree的解析和script的解析通常是交替进行的。