一道经典面试题:从输入URL到页面加载完成经历了那些?当然这个问题很多同学应该已经看了无数次,这个问题不仅考察我们对整个链路的熟悉程度,它跟性能优化也是息息相关,只有当你熟悉了每个细点的时候,才有可能抓住每个可优化的地方。
概述
首先我们简单列一下主要流程:
- 域名解析,查找域名对应的ip地址
- 与服务器建立连接
- 浏览器发送请求
- 浏览器接收响应并渲染
- 连接关闭
域名解析
- 为什么要进行域名解析?
为了更方便的记住网站,会用字母和数字组合来代替纯数字的 IP 地址,IP 协议为互联网上的每一个网络和每一台主机分配的一个地址,IP地址就想当于主机的唯一标示,服务器本质也是一台主机,想要访问某个服务器,必须先知道它的 IP 地址。 - 如何查找域名对应的IP地址?
- 首先会在浏览器缓存中查找,比如在chrome下,可以在浏览器中输入
chrome://net-internals/#dns
来查看当前的缓存列表,或者清除缓存。 - 操作系统的缓存中查找。
- 本地host配置文件查找(比如有时候我们通过修改host文件来做代理)。
- 路由器DNS缓存查找。
- LDNS(本地域名服务器)迭代查询,也就是针对域名一级一级去查询最终的IP地址。比如访问a.qq.com,LDNS会先去查找根域名服务器,它会返回com的授权服务器,然后再去查找com的服务器,他会返回qq.com的授权服务器,以此类推,查找到之后做缓存并返回给浏览器。
与服务器建立连接
通过DNS查询我们已经获取到了服务器IP,接下来就可以进行TCP连接。TCP是一种面向有连接的传输层协议,它可以保证客户端和服务端之间的通信可达,他能够处理在传输过程中丢包、乱序等异常情况,此外他还能有效利用宽带,缓解网络拥堵。
-
三次握手
发送请求
与服务器建立连接之后,浏览器向服务器发起http请求,请求消息包含:请求行、报头、请求体。
请求行包含了方法、URI、协议版本,比如:GET http://a.qq.com HTTP/1.1
报头主要是Header中的信息,这里不做赘述。
请求体包含了要传给服务器的信息,常见的比如query参数。
接收响应
- 响应消息
响应消息也是由三部分构成:状态行、报头以及响应正文。
状态行包含协议版本、状态码等。
报头包含普通报头、请求报头、响应报头和实体报头。
响应正文就是响应的内容,比如我们请求一个网站,正文就是这个网站的html。 - http缓存简述
这里会涉及到另一个经典面试题:http缓存。就像DNS解析域名缓存一样,请求内容也会有缓存,简单总结就是,如果有缓存并且没有过期会优先使用本地缓存(此时不会发起http请求),如果缓存过期了,那么服务端会判断内容是否有变化,如果没有变化则不反回实体,继续使用本地缓存,否则按照正常请求返回内容。 - 页面渲染
接收到响应后,浏览器首先会解析HTML文档(为了页面更快的呈现,这里不会完全解析完才进行下一步),然后构建渲染树(DOM树、CSSOM树),再然后开始渲染页面、显示内容,这里就会涉及到经典面试题Reflow和Repaint。当然在渲染过程中还可能会继续发起请求(js、css、图片等)。
断开连接
这里就是四次挥手
这里大家可能有疑问,既然客户端都请求断开了,为什么服务器不立刻断开?这是因为有些数据可能还在传输中,所以要确认数据全都发送完毕。
总结
整个过程基本是以上几大步骤,当然每一步还有更细节的内容,这里不做展开。当你理解了整个过程后,再去做性能优化可以起到事半功倍的效果。