一个网页被解析的过程

一个网页被解析的过程

了解浏览器如何请求、渲染最后呈现出一个漂亮的页面,对于了解网页解析效率的瓶颈,提高网页的加载速度有很大帮助。

每个页面或者页面组件都是根据url去请求的,url的结构一般如下:

http://host.com/path/……path/filename?param1=”param1″&param2=”param2″#hash

[协议(http:或者https:等)]+“//”+[主机域名(host.com)]+[文件路径(/path/……path/filename)]+[GET参数(?param1="param1"&param2="param2")]+[hash]

协议和主机域名是必须的,文件路径参数hash等可选(无文件路径的话,服务器更具配置返回特定的default页面)。

DNS查询

http或者https协议都依赖于传输层协议tcp的,而tcp协议依赖于网络层的IP协议。所以要在服务器和客户端之间传输文件,必须首先知道服务器的IP。绝大多数的url都是使用域名的(当然也可以直接指定IP(访问谷歌:http://74.125.71.99)),这样每次请求页面或者组件时,都需要通过DNS查询域名的IP地址。

下面是访问http://www.douban.com,使用wireshark过滤dns请求的截图:

一个网页被解析的过程_第1张图片

可以确定以下几点:

  1. 浏览器缓存DNS查询,过期时间不一。
  2. 不同的浏览器对于DNS查询在不同窗口或者tab之间是否共用缓存结果不一(chrome下刷新被视全新的请求)。
  3. 同一页面共用DNS结果,即请求同页面同源的组件不会进行重复的DNS请求

结论:一般情况下,每次请求页面或者组件会根据DNS缓存有无和可用与否,进行不定的DNS查询。解析时间与本机缓存或者直接DNS服务器缓存命中与否有关,多在0ms到1000ms之间。

HTTP请求和响应

通过DNS查询获得主机IP地址之后,进过TCP三次握手建立HTTP链接,开始发送HTTP请求,HTTP请求分为三部分:请求行,请求头和请求数据(发送POST请求时),示例:

GET / HTTP/1.1(请求行)
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: www.google.cn
Connection: Keep-Alive

POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley(POST数据)

服务器接到HTTP请求,就调用相关资源,计算得出要响应给客户端的资源(html,xml,image,json,flash等等),然后发出HTTP响应:

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
<head></head>
<body>
<!–body goes here–>
</body>
</html>

于是客户端接收响应的数据,进入下一步,对页面进行解析。

解析DOM

学院说法:根据html嵌套关系,得到树形的DOM树,根据出现的样式构建Style Object,结合DOM树和Style Object reflow得到Render Tree,然后通过图形API绘制出来。接下去就是loop:dom和style改变触发事件->reflow->repaint

实际实验:demo

该页面包含了数个<script type=”text/javascript”> debugger; </script>,一个<h>和一个<img>以及一些存在于<head>和<body>的样式。通过debugger对去页面解析的截断作用,可以发现以下几点:

  • 根据html的树形结构顺序解析文档,所有组件(外部的javascript、css、image等)无预加载,只有被解析到的时候才会加载解析。边解析边更新DOM树和Style Object且重新绘制页面。
  • 网页解析是单线程的,JavaScript的执行会阻塞网页的解析。
  • image、flash等组件的加载不会阻塞网页的解析。javaScript load时不会阻塞页面解析,执行时阻塞页面解析。
  • 超时或者长时间加载的组件不会阻塞页面解析,javascript会因为顺序执行而阻塞之后的代码。

JavaScript的执行

JavaScript是如何执行的?每段<script>标签中的script都在全局作用域内分段开启新的context执行,生成一个活动对象,在代码执行前需要欲处理,顺序地,对于代码中的每个函数声明创建活动对象的属性,值为创建函数的返回值。对于变量声明则创建为活动对象的属性,且值为undefined,假设变量和函数声明的属性重名,则保持原函数值不变。预处理结束后,就按照顺序执行代码。

Close

包括关闭和重定向到其他页面。

关闭之前,将会触发一些事件:onbeforeunload(微软自定义的),接着触发unload事件。结束所有该页面使用的进程,比如说flash视频,不同浏览器有不同的处理方式。有的运行在同一个进程中,而有的运行在独立的进程里。

ps:该篇文章给出了个大体的框架,以后会随着了解的不断深入而补充更多的东西,欢迎大家指出错误或给予补充,不断完善,说明问题是最终目标。

你可能感兴趣的:(一个网页被解析的过程)