一个页面从输入 url 到加载完成 这个过程发生了什么

先来了解以下 五层因特尔协议栈

  • 应用层(dns http) DNS 解析成 ip 并完成 http 请求发送
  • 传输层(tcp udp)三次握手四次挥手建立 tcp 链接
  • 网络层 (ip ARP) IP 寻址
  • 数字链路层 将请求数据封装成帧
  • 物理层 利用物理介质传输比特流

简介版本

  1. 浏览器根据请求的 url 交给 DNS 解析 找到这真实 IP 向服务器发起请求
  2. 服务器交给后台处理完成后返回数据,浏览器接收文件(html,css javascript) 等
  3. 浏览器对加载到的资源进行语法解析,构建相应的内部数据结构(Dom 树 css 树 render 树等)
  4. 载入解析到的资源文件渲染页面完成

详细版本

  1. 浏览器开启一个线程来处理这个请求,对 url 进行判断,如果是 http 协议,则就按照 web 的方式来处理
  2. 浏览器解析 url,一般我么输入的都是服务器域名,我们会先查找对应的 ip
  3. 首先会查看浏览器的 DNS 缓存,如果存在,则域名解析到此完成
  4. 如果浏览器自身的缓存没有找到相应的条目,就会尝试读取操作系统的 host 文件来看时都存在对应的映射关系
  5. 如果 host 文件没有,继续查找本地的域名服务器
  6. 如果本地的域名服务器还没有找到的话 ,它就会向跟服务器发出请求,进行递归查询
  7. 查到了 IP 地址,会将记录存储在本地缓存,此时网络层便会通过 ip 地址寻得对应服务器的物理地址
  8. 寻得服务器的地址 客户端在网络传输层便可以和服务器通过三次握手建立 TCPIP 链接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TCPIP请求

http的本质就是TCP/IP请求
需要经历三次握手建立链接 4次挥手断开连接
TCP将http长报文划分为短报文,通过三次握手与服务器建立链接进行可靠传输

三次握手

1. 客户端:你是XX服务器吗
2. 服务端:我是XX服务器,你是客户端吗?
3. 客户端:是的 我是客户端
成功

四次挥手
主动方:我已经关闭了向你那边的信息发送通道,只能被动接受信息了
被动方:收到通道关闭信息
被动方:我现在也关闭了
主动方:收到消息 连接断开 之后双方无法通信

TCPIP请求:浏览器在同一个域名下并发的TCP链接是有限制的(2-10个)

  1. 链接成功后 链路层将请求数据封装成帧
  2. 最后物理层通过物理介质进行传输
  3. 到了服务器就会通过相反的方式将数据一层一层的还原回去
  4. 请求到了后端服务器一般都会有统一的验证 如安全验证,跨域验证等,验证未通过就直接返回相应的 http 报文
  5. 验证通过后就会进入后台代码 此时程序收到请求执行相应的操作(如查询数据库等)
  6. 如果浏览器访问过 且缓存上有相应的资源便会与服务器最后的修改时间对比,一致便返回 304 告诉浏览器可以使用本地缓存
  7. 前端浏览器接收到响应成功的报文便开始下载网页
    下载完的网页交给浏览器的内核(渲染进程)进行处理
1
2
3
4
5
6
7
8
9
10
11
12
* 根据顶部定义的DTD类型进行相应的解析方式
* 渲染进程内部是多线程的 网页的解析会被交给内部的GUI渲染进程处理
* 首先渲染进程中的html解释器将html网页和资源从字节流解释转化为字符流
* 再通过词法分析器将字符流解释成词语
* 之后通过语法分析器根据词语构成节点,最后通过这些节点组建一个DOM树
* 这个过程中 如果遇到的DOM节点是js代码,就会调用js引擎对js代码进行解释执行。此时由于js引擎和GUI渲染进程的互斥,GUI渲染就会被挂起,渲染过程停止;如果js代码的运行中对dom树进行了修改,那么都没树的构建需要重新开始
* 如果节点需要依赖其他资源(图片 css)便会调用网络模块的资源去加载它们,但他们是异步的所以不会阻塞当前dom树的构建
* 如果遇到的是js资源url(没有标记异步)则需要停止当前dom的构建 直到js的资源加载并被js引擎执行后才继续构建dom
* 对于css css解释器会将css文件解释成内部表示结构(同html解析 子节流->字符流->词语->节点),生成css规则树
* 然后合并css树和dom树,生成render渲染树
* 最后对render树进行布局和绘制,并将结果通过IO线程传递给Browser控制进程(浏览器主进程)进行显示