最近一直在思考从url到页面展示这个问题的具体答案,查询了相当多的资料,也看了看关于《图解HTTP》这本书,对于这个在前端界一直讨论不休的问题有了一些些自己的见解和观点,阐述出来,还请各位多多斧正不胜感谢�。
- 在我看来主要的发生时间有以下几件:
- URL的输入
- DNS解析
- TCP的连接
- 服务器处理请求和处理
- 浏览器处理和渲染
1. URL的输入
在进行URL输入的阐述之前,我觉得有必要现对于URL有一个介绍和说明。
URL(Uniform Resource Locator),统一资源定位符,有时候也会被人俗称为网页,然而URL的真是身份就是网站网址,主要作用就是定位互联网上资源。一般来说URL的格式主要是
协议类型:[//服务器地址[:端口号]][/资源层级UNIX文件路径]文件名[?查询][#片段ID]
其中需要重点介绍的就是协议类型,一般有以下几种
- http (超文本传输协议)
- https(超文本传输协议的安全版)
- ftp(文件传输协议)
- file
2. DNS的解析
DNS解析的过程就是寻找哪台机器上有你需要资源的过程。当你在浏览器中输入一个地址时,例如下面这个百度网的地址<www.baidu.com>,其实不是百度网站真正意义上的地址,他只是百度网站的一种表现形式,实际上百度的的真正IP为119.75.217.109。互联网上每一台计算机的唯一标识是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度的网址。所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到IP地址的转换。
一般来说DNS的解析主要的步骤分为以下几种:
- 在本地域名服务器中查询IP地址。
- 在本地的域名服务器中没有找到的情况下,本地域名服务器会向根域名服务器发送一个请求,进一步进行解析查找。
- 如果根域名服务器也不存在该域名时,本地域名会向com顶级域名服务器发送一个请求,依次类推下去。直到最后本地域名服务器得到真正的IP地址并把它缓存到本地,供下次查询使用。
从上述过程中,可以看出网址的解析是一个从右向左的过程: com -> baidu.com -> www.baidu.com。但是你是否发现少了点什么,根域名服务器的解析过程呢?事实上,真正的网址是www.baidu.com.,并不是我多打了一个.,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上,所有网址真正的解析过程为: . -> .com -> baidu.com. -> www.baidu.com.。
3. TCP的连接
TCP连接的主要作用是为实现数据的可靠传输,TCP要在应用进程间建立传输连接。它是在两个传输用户之间建立一种逻辑联系,使得通信双方都确认对方为自己的传输连接端点。
根据所查询的资料介绍来看,对于TCP连接同样也分为三个部分:
- 建立连接前,服务器端首先被动打开其熟知的端口,对端口进行侦听。
- 当客户端要和服务器端建立连接时,发起一个主动打开端口的请求(该端口一般为临时端口)。
- 然后进入三次握手的过程。
4. 服务器的处理请求
一般来说,服务器的请求处理分为两个情况
- 服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404错误。
- 如果服务器的请求返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,则会重新从前几个步骤再次获取。
5. 浏览器的处理和渲染
浏览器在收到了服务器发送过来的HTML、CSS、JavaScript以后开始进行处理和渲染,这个步骤是整个部分中最核心,也是最为复杂的部分。
在浏览器的解析和渲染中一般分为两个部分:
- HTML和CSS的处理与渲染
我们要知道浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。 - JS的处理和渲染
JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。
总结
以上只是最基本的步骤,实际不可能就这么简单,一些可选的步骤例如网页缓存、连接池、加载策略、加密解密、代理中转等等都没有提及。即使基本步骤本身也有很复杂的子步骤,TCP/IP、DNS、HTTP、HTML:每一个都可以展开成庞大的课题,而浏览器的基础——操作系统、编译器、硬件等更是一个比一个复杂。不是计算机专业的同学看了上面的解释完全不明白是很正常的,可能会问为什么要搞得那么复杂,但我保证这每一个步骤都经过深思熟虑和时间的考验。你输入URL即可浏览互联网,而计算机系统在背后做了无数你看不到的工作,计算机各个子领域无数工程师为此付出你难以想象的努力。