URL到页面显示过程

当输入URL、敲下回车、最后浏览器页面显示,这里面有什么故事?键盘到操作系统、操作系统到浏览器、浏览器到服务器、服务器返回数据页面渲染……

键盘到操作系统

回车键按下时,与键盘相关的电路闭合,通过消抖操作,键盘的电路系统将回车键转化为键码13。按键被按下会触发中断事件,回车键的键码被编码并通过通用串行总线(USB)传输到中断请求线上(IRQ),中断控制器接收到IRQ上的信号后,会映射一个中断向量。中断描述符表将中断向量映射到对应的处理函数上(中断处理器)。


操作系统到浏览器

操作系统通过相应的API函数获取到当前的活动窗口(该浏览器)并获取到当前浏览器地址栏句柄,操作系统使用sendMessage函数将消息添加到地址栏句柄的消息队列中,sendMessage函数参数将带有按键以及按键的信息。然后浏览器地址栏句柄的消息处理函数将被调用,处理消息队列中的消息。


浏览器到服务器

处理URL

关键字or地址:浏览器搜先分析地址栏的内容是关键字还是URL。若地址栏的为关键字,则使用浏览器的搜索引擎搜索该关键字。当把文字作为关键字传递给搜索引擎时,通常会在URL后面加上一个参数,这个参数告诉搜索引擎搜索来自哪个浏览器。 
这里写图片描述

HSTS列表: HSTS强制客户端使用HTTPS与服务器创建连接。若访问的URL在HSTS列表里,则浏览器会把HTTP协议变为HTTPS。

编码: 对URL进行Unicode编码

DNS查询

浏览器处理完URL后,将获取要访问的URL所在服务器的地址。这时需要进行DNS查询。

DNS查询过程:

  1. 查询本地DNS缓存
  2. 查看本地host表
  3. 查询DNS服务器

在DNS服务器上进行查询时,首先查询本地DNS服务器。若本地DNS 
服务器上有域名的缓存,则本地DNS服务器将对应IP发送给查询方。若本地DNS服务器上没有域名的缓存,则向根域名服务器发起查询(递归)。根域名服务器收到请求后,会返回下一级域名信息的DNS服务器地址。本地DNS服务器收到地址后继续进行查询(迭代),最后获取到目标域名的IP并发送给查询方。 
这里写图片描述

TCP连接

此时获取到URL中域名的IP地址,通过协议可以获取到端口(HTTP:80、HTTPS:443),下一步该进行浏览器与服务器之间的连接。

浏览器使用socket函数来进行TCP连接,初始化socket时参数为 AF_INETSOCK_STREAM

TCP建立连接过程(三次握手):

  1. 客户端发送一个TCP包。设置SYN=1(请求建立连接)、Seq=X(随机产生的序列号)
  2. 服务器发回确认包(ACK)应答。SYN=1、ACK=1、ACK number = X+1、Seq = Y(随机产生)
  3. 客户端再次发送确认包(ACK) 。SYN=0、ACK=1、ACK number= Y+1、Seq = X+1

客户端客户端服务器服务器SYN=1,Seq=XSYN=1、ACK=1、ACK number=X+1、Seq=YSYN=0、ACK=1、ACK number=Y+1、Seq=X+1

TCP断开连接过程(四次挥手):

  1. 客户机给服务器一个FIN为1的TCP报文
  2. 服务器返回给客户端一个确认ACK报文
  3. 服务器给客户端发送一个FIN报文
  4. 客户机回复ACK报文

客户端客户端服务器服务器FIN=1ACK=1FIN=1ACK=1

服务器动作

从浏览器发起请求到请求到页面数据的过程中,可能会经过负载均衡等中间部分

负载均衡

方式 说明 特点
HTTP重定向 浏览器向web服务器请求某个URL后,web服务器可以通过http响应头信息中的Location标记来返回一个新的URL 主站点服务器的吞吐率平均分配到了被转移的服务器;重定向的服务器工作量不同,实际的负载量不可估计
DNS负载均衡 在DNS服务器中配置多个A记录,将这些A记录对应的服务器构造成集群,,例如CDN 可以根据用户IP选择最近的服务器,无法记录HTTP请求上下文
反向代理 转发http请求(应用层),常用nginx 所有HTTP请求都必须经过代理,可以为不同的实际服务器设置不同的权重,要求并发处理能力要求高,可以可以监控后端服务器
IP负载均衡 网络层通过修改请求目标地址进行负载均衡(网络层) 吞吐率高,要求网络带宽大

请求处理

  1. 服务器收到请求后将请求解析为:请求方法、域名、请求路径
  2. 服务器找到该域名对应的虚拟主机,并验证该虚拟主机是否可以使用该请求方法
  3. 服务器获取请求路径对应的内容,并根据内容使用指定的程序来处理(e.g.使用不同的程序解析PHP、JSP等文件),将输出的结果发送给浏览器

PLUS - 请求方法

方法 描述
GET 请求指定的页面信息,并返回实体主体。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)
PUT 从客户端向服务器传送的数据取代指定的文档的内容
HEAD 与get类似,不过返回的响应中没有具体的内容,用于获取报头
DELETE 请求服务器删除指定的页面
OPTIONS 返回服务器针对特定资源所支持的HTTP请求方法
TRACE 回显服务器收到的请求,主要用于测试或诊断
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

浏览器页面渲染

浏览器收到服务器返回的页面数据后,开始对页面进行渲染

浏览器进程与线程

浏览器是多进程的,用于页面显示的有Browser进程、第三方插件进程、GPU进程(3D绘制等)、浏览器渲染进程(浏览器内核,每个Tab页面都有一个渲染进程)。

浏览器渲染进程包含的线程:

  • GUI渲染线程
  • JS引擎线程
  • 事件触发线程
  • 定时器触发器线程
  • 异步http请求线程

注意: JavaScript可以操作DOM,如果修改元素的时候同时渲染页面,就可能出现不可预料的结果,所以GUI渲染线程与JS引擎线程是互斥的

浏览器渲染页面过程

  1. 解析HTML建立dom树
  2. 解析css构建render树(将CSS代码解析成树形的数据结构,然后结合DOM合并成render树)
  3. 布局render树(确定每个节点在屏幕上的位置)
  4. 绘制render树(遍历render树,并使用UI后端层绘制每个节点) 
    这里写图片描述 
    这里写图片描述

CSS加载是否会阻塞dom树渲染?

  • css加载不会阻塞DOM树解析
  • css加载会阻塞render树渲染

回流和重绘

  • 回流:浏览器重新渲染部分或全部文档的过程
  • 重绘:元素改变的样式不影响元素位置时,浏览器将新样式赋予给元素并重新绘制它的过程