从输入URL到渲染页面发生了什么?
简单来说:
- 域名解析
- 发起TCP三次握手建立连接
- 建立连接后发起http请求
- 服务器响应请求,浏览器获取html源码
- 浏览器解析html代码,并请求相关css,js和图片资源
- 浏览器渲染页面
然后先上一张比较直观的图
那么既然层次中,TCP在HTTP下一层,为什么是先建立TCP连接呢?
因为 http是不是一种面向连接的协议,在应用层中,仅仅是生成了http请求的信息和数据,但无法直接发送,所以才需要先建立tcp连接。tcp在将http请求信息发送之前,会将其分割,并在各个报文上打上标记,然后继续发送给网络层。
服务器收到http请求后,后台开始工作,如负载平衡,跨域等,然后生成响应数据包(响应头和相应体),发给客户端,客户端(浏览器)开始解析和渲染:
- 开始解析html文件,当然是自上而下,先是头部,后是body;
- 解析头部文件 --- 当解析到头部css和js外部链接时,同步下载(某些js可以在需要时才动态添加到dom中);
- 生成DOM树 --- 接着解析body部分,边解析边开始生成对应的DOM树,同时等待css文件下载;
- 利用CSS渲染DOM --- 一旦css文件下载完毕,那么就同步去用已经生成的DOM节点+CSS去生成渲染树;
- 计算渲染树的布局 --- 渲染树一旦有结构模型了,接着就会同步去计算渲染树节点的布局位置;
- 继续渲染;
- 渲染过程中若碰到图片,就开始同步下载,并跳过该位置进行后面的渲染,图片下载好后再回来渲染;
- 渲染完毕,执行onload
细说一下:
1. 域名解析 -- 缓存
先在浏览器缓存、本地host文件查找。如果没有,就在本地DNS服务器查找,如果也没有,就开始依次向根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存发送请求,每到一个服务器都会先查缓存。
2. 域名解析 -- 递归解析和反复(迭代)解析
递归解析:客户端发出请求(example.microsoft.com)给本地DNS服务器之后,就开始一直处于等待状态。然后本地服务器向根域名服务器查找.com的地址,然后到顶级名称服务器中查找microsoft.com的地址,然后到二级名称服务器中查找example.microsoft.com的地址,最终找到权威名称服务器,里面就存放了example.microsoft.com的ip地址。
迭代(反复)解析:与迭代解析的区别是,本地域名服务器不再作为一个代理,而是只负责查找本地缓存,若缓存没有,则告诉客户端应该去哪些服务器查找,如下: