URL到页面的过程

475 阅读5分钟

1.过程概述

  1. dns解析域名获得IP(在这个之前还有浏览器进程检查url,组装协议,构成完整的url的过程)
  2. 浏览器根据IP与服务器建立TCP连接
  3. 浏览器发起HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 浏览器与服务器断开连接

2.dns解析域名获得IP

域名解析的过程是逐级查询的 
查看dns解析记录 dig math.stackexchange.com

dns解析域名的过程如下:

  1. 浏览器缓存
  2. 操作系统缓存
  3. host文件中查找
  4. 由器缓存
  5. ISP DNS缓存 互联网服务提供商(阿里 百度之类)
  6. 顶级DNS服务器/根DNS服务器
    dns解析过程

3.TCP连接 Browser Service

  1. 三次握手与四次挥手
  • 三次握手 确认发送方与接收方的 发送接收能力
  1. Browser ——> Service Browser发送SYN包SYN=1,初始序号seq=x 进入SYN-SENT状态 等待Service确认
  2. Service ——> Browser Service发送确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y 进入SYN-RECEIVED状态
  3. Browser ——> Service Browser发送确认报文段ACK=1,确认号ack=y+1,序号seq=x+1 进入ESTABLISHED状态 等待Service收到包之后 状态切换为ESTABLISHED
  • 四次挥手
  1. Browser ——> Service Browser发出连接释放报文段(FIN=1,序号seq=u)停止再发送数据 主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认 B:我要走了
  2. Service ——> Browser 服务端收到 FIN 之后 Service发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v)服务端进入CLOSE_WAIT(关闭等待)状态 客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态 S:我知道了
  3. Service ——> Browser Service发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态 S:我也要走了
  4. Browser ——> Service Browser发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态此时TCP未释放掉,服务端进入LAST_ACK,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。B:知道了,再见

3.HTTP请求与响应

http(hyper text transfer protocol) 超文本传输协议,即定的规则,简单介绍HTTP的的请求响应格式,其中的各个字段意义移步http MDN

  1. 请求
> 请求HTTP的格式
    请求类型 请求URL 协议版本 扩展内容
    请求头内容
    Accept、Accept-Encoding、Accept-Chearset、Cookie、Host、user-agent...
    空行
    请求主体
  1. 响应
> 响应HTTP的格式
    协议版本 响应状态码 描述  扩展内容
    响应头内容
    Content-type、Content-Encoding、Etag、Last-Modified、Pragma、Expires、Cache-Control、Date...
    空行
    响应主体

2.二次请求时,判断是否是有缓存可使用 - 缓存相关文章移步GitHub

4.浏览器解析渲染页面 webkit && gecko

  1. 处理HTML生成DOM tree
  1. 将http请求返回的原始字节转为字符 bytes => Characters(<html>...</html>
  2. 将字符通过词法分析(XML)转为Tokens Characters(<html>...</html>) => Tokens Token中会标识出当前Token是“开始标签”或是“结束标签”亦或是“文本”等信息
    处理HTML生成DOM tree
  3. Token转化为节点对象(第2,3步骤同时进行) Token => Node DOM Token转化完毕 生成DOM tree

HTML生成DOM tree

注意:带有结束标签标识的Token不会创建节点对象,上图表示构建DOM的具体步骤。首先生成出htmlToken,并消耗Token创建出html节点对象。然后生成headToken并消耗Token创建出head节点对象,并将它关联到html节点对象的子节点中。随后生成titleToken并消耗Token创建出title节点对象并将它关联到head节点对象的子节点中。最后生成bodyToken并消耗Token创建body节点对象并将它关联到html的子节点中。

  1. 处理CSS标记生成 styleSheets(CSSOM)
  1. 将http请求返回的原始字节转为字符 bytes => Characters(body{...} p{...}
  2. 将字符通过词法分析转为CSS分析树Token Characters(body{...} p{...}) => Tokens
  3. 将Tokens转为CSS规则树状图,并保持于每个元素和对应样式的映射关系 最终生成styleSheets
  1. 合并DOM tree 和 styleSheets 生成 render tree(webkit)或 frame tree(gecko)

生成渲染树的阶段DOM节点在styleSheets中根据元素,类,节点,ID选择器来提取与之对应的一条会多条CSSRule,提取完成,渲染树构建完成。 CSS样式有层叠的权重关系,后面的CSS可能会影响前面的CSS,必须等所有的CSS解析完成才能构建出准确的styleSheets,必须等整个styleSheets构建完成才能进行下一个阶段

注意:
1. 构建DOMtree 与 styleSheets 是同时进行的 但是当遇到没有defer、async的script标签,DOMTree的构建将被暂停,直至脚本执行完毕
2. JavaScript可以查询和修改DOMTree与styleSheets
3. 直至CSSOM构建完毕,JavaScript才会执行
4. 即:JS会阻塞DOMtree的构建 styleSheets会阻塞JS的执行 JS顺序排放应在CSS的后面 避免styleSheets的长时间单独构建
  1. 渲染引擎进行布局阶段(layout)
  1. 计算每个元素的几何坐标位置,并将这些信息保存在layoutTree中
  2. 为特定的节点生成专用的图层,并生成一棵对应的图层树layerTree
  1. 绘制阶段(paint)
  1. 浏览器渲染引擎实现每个图层的绘制,把一个图层的绘制拆分成按照顺序的待绘制指令列表 ++可以打开“开发者工具”的“Layers”标签,查看图层及图层的绘制列表++
  2. 绘制列表提交给合成线程,合成线程会将图层划分为图块,计算当前的视口,优先绘制当前视口附近的图块生成位图(过程成为栅格化,GPU进程中完成),所有图块栅格化完成,合成线程发送DrawQuad命令给浏览器进程,将页面内容绘制到内存,并显示到屏幕

浏览器渲染过程

参考文章

  1. 从输入url到页面展现发生了什么?
  2. TCP/IP 是如何工作的
  3. DNS解析、三次握手与四次挥手
  4. TCP与TCP连接详解
  5. 三次握手与四次挥手
  6. 浏览器的渲染过程
  7. css加载会造成阻塞吗?