浏览器请求与响应全过程详解

3. 浏览器请求与响应全过程详解

前言

当在浏览器上输入一个网站链接时,它是如何运行将网页内容呈现在我们的浏览器上的呢?

本文旨在对www.yangoogle.com网页进行详细分析,了解浏览器展示内容的整个流程。下图是在网上检索到一个较清晰的流程图,本文通过这张图进行展开讲解:

  • 首先,对输入的url进行DNS解析(找出对端服务器ip地址)
  • 通过ip地址,建立TCP请求(三次握手协议)
  • 发送HTTP请求与响应
  • 解析渲染服务端的响应数据
  • 断开TCP连接

《浏览器请求与响应全过程详解》

流程

1.解析域名(DNS查询)

DNS(Domain Name System,域名系统)因特网上作为域名和IP(Internet Protocol Address)地址相互映射。

优点:通过域名访问ip,可以不用记住繁杂的ip数字串。

查询规则

简单来说,一条域名的DNS记录会在本地有两种缓存:

  • 浏览器缓存
  • 操作系统(OS)缓存

在浏览器中访问的时候,会优先访问浏览器缓存,如果未命中则访问OS缓存,最后再访问DNS服务器(一般是ISP提供),然后DNS服务器会递归式的查找域名记录,然后返回。

查询浏览器缓存

浏览器会缓存DNS记录,在chorme中,输入下面指令就可以查看:
chrome://net-internals/#dns

可以查询到yangoogle.com对应的ip地址(当前ip显示已经过期)

《浏览器请求与响应全过程详解》

查询本地host文件

当按下回车键起,一个HTTP请求就已经开始发出了。那么,浏览器首先要做的就是解析这个域名,通过本地的host文件(ps:推荐一款修改host文件的神器swtichhost)里面的ip地址查询。

如下图,我将yangoogle.com域名对应的ip地址修改为本机地址(127.0.0.1)。当我访问**//www.yangoogle.com**之后,不出意外,结果显示404未找到该页面。

《浏览器请求与响应全过程详解》

这是因为输入的域名(yangoogle.com),映射的ip地址(127.0.0.1)并没有找到正确的资源,因此会返回404。

注意

利用上面的特性,可以将任意域名映射到指定的ip地址上,这样就可以达到欺骗的目的。这也是常用的一种病毒手法。

查询系统DNS缓存

如果浏览器中还没有,就在系统缓存中查询:

  • mac 指令
$ nslookup yangoogle

《浏览器请求与响应全过程详解》

  • windows 指令
$ ipconfig /displaydns

拓展

DNS服务器

如果上面查询到未得到匹配的ip地址,那么浏览器会想DNS服务器发送一条DNS查询的请求,流程如下:

  • 路由器缓存

如果系统缓存中没有找到匹配的IP,那么接着会发送一条请求到路由器上,然后路由器在自己的缓存中匹配查询记录

  • ISP DNS缓存

如果本地路由器也没有匹配到,这个请求就会发送到ISP(互联网服务器提供商,简称宽带运行商),ISP也有对应的DNS服务器。

注意
如果万恶的运营商对你查询的DNS服务器进行修改的话,跳转他们指定的页面上,或对你的网页注入广告之类的,这样他们就到达营收的目的。这也就是常见的DNS劫持

  • 递归查询

如果连ISP的DNS服务器上都没有查询到的话,那么,你的ISP服务器会向根域名服务器进行搜索。根域名服务器是面向全球的顶级服务器(.com、.cn、.org等)。

例如:我们要查询:test.yangoogle.com

在ISP之前都没有查询到,在顶级DNS服务器上查询到

  1. 首先,匹配到.com一级域名服务器,请求转发到.com域名服务器。
  2. 然后,匹配到.yangoogle的二级域名服务器,请求接着转发到.yangoogle服务器。
  3. 最后,匹配到test这个三级域名的ip地址。
  • 多ip域名DNS查询

有一种场景,就是一个域名对应多个ip地址(服务器地址)。

这种方式的目的是为了解决DNS查询时间的问题:

  1. 循环DNS 多个ip列表循环返回DNS查询
  2. 负载均衡 设计一个特点的ip负载均衡服务器,负责监听请求并转发给后面多个服务器集群,实现多个服务器负载均衡。
  3. 地理DNS 根据用户的地理位置,按距离返回最近的ip地址

《浏览器请求与响应全过程详解》

2.TCP连接

在查询到域名对应的ip地址之后,,浏览器设置Remote Address,以及端口号port等信息。确保传输层的正常通信(即TCP正常连接)

  • 生成TCP数据包
  • 建立TCP连接
  1. 三次握手(HTTP)
  2. TSL握手(HTTPS)

ip.src == 175.45.4.110 or ip.dst == xx.xx.xx.xx

《浏览器请求与响应全过程详解》

《浏览器请求与响应全过程详解》

《浏览器请求与响应全过程详解》

3.发送http请求

传输层通过已经建立完成,那么就准备发送http请求。

《浏览器请求与响应全过程详解》

可以查询到http请求体的一些常见设置:

  • Request URL 定位请求资源位置
  • Request Method 请求方式
  • Status Code 状态码:200(服务器已经成功处理)
  • Remote Address (服务器ip地址)
  • Referrer-Policy 用户代理行为

4.接收服务器响应

《浏览器请求与响应全过程详解》

在服务器端接收来自浏览器的请求之后,服务端做出了相应的增删改查操作之后,返回相应的Content-Type。浏览器通过不同的Content-Type做出不同的解析。

当我们请求一个.html类型的页面文件时,服务器端就将Content-Type设置为text/html

同时,服务端也可以设置Cookie的过期时间(Expires),是否使用压缩(Content-Encoding)

Etag 标识符

Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等。具体内部含义是使服务器控制的,就像Cookie那样。

《浏览器请求与响应全过程详解》

《浏览器请求与响应全过程详解》

5.解析

《浏览器请求与响应全过程详解》

当服务端返回.html文件之后,接下来,浏览器就要对response的内容进行渲染

let arr = []
for (let item in document){  
    arr.push(item)
}

console.log('dom',arr)

Webkit有三个C++的类对应这三类文档,解析这三种文件会产生一个DOM Tree。

  • CSS,解析CSS会产生CSS规则树。

  • Javascript,主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rule Tree.

  • 解析HTML,生成DOM树
    通过对response进行词法分析,生成对应的AST。在解析HTML过程中,网页永远不会出现无效语法,因为浏览器本身具有一定的容错机制,会自动补全修复错误内容,然后继续解析。

  • 解析CSS

根据css的词法和语法分析,挂载到全局的样式表对象中(CSS StyleSheet)

  • 解析JS

因为浏览器的UI线程是单线程的:主要执行js执行和渲染界面。
(js可以控制UI的绘制

因此,当js处于加载中的状态时(padding),就会导致页面阻塞。阻塞期间,浏览器不会执行其他行为的,这就会出现一定时间的空白期。

6.渲染

解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。
基本步骤:

  • 计算CSS样式
  • 构建Render Tree
  • Layout – 定位坐标和大小,是否换行,各种position, overflow, z-index属性
  • 开画

《浏览器请求与响应全过程详解》

上图流程中有很多连接线,这表示了Javascript动态修改了DOM属性或是CSS属会导致重新Layout,有些改变不会,就是那些指到天上的箭头,比如,修改后的CSS rule没有被匹配到,等。

DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。 所以,下面这些动作有很大可能会是成本比较高的。

  • 当你增加、删除、修改DOM结点时,会导致Reflow或Repaint
  • 当你移动DOM的位置,或是搞个动画的时候。
  • 当你修改CSS样式的时候。
  • 当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候。
  • 当你修改网页的默认字体时。
    注:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。

注意:

  1. 这里重要要说两个概念,一个是Reflow,另一个是Repaint。这两个不是一回事。

Reflow的成本比Repaint的成本高得多的多。

  • Repaint —— 屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。

  • Reflow —— 意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow)reflow 会从这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。

减少reflow/repaint

  • 不要一条一条地修改DOM的样式。与其这样,还不如预先定义好css的class,然后修改DOM的className。
  • 把DOM离线后修改
// bad
el.style.left = left + "px";
el.style.top  = top  + "px";
// good
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
  • 不要把DOM结点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。
  • 尽可能的修改层级比较低的DOM。当然,改变层级比较底的DOM有可能会造成大面积的reflow,但是也可能影响范围很小。
  • 为动画的HTML元件使用fixed或absoult的position,那么修改他们的CSS是不会reflow的。
  • 千万不要使用table布局。因为可能很小的一个小改动会造成整个table的重新布局。
  1. Rendering Tree 渲染树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在渲染树中了。
    CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element。也就是DOM结点。也就是所谓的Frame。 然后,计算每个Frame(也就是每个Element)的位置,这又叫layout和reflow过程。
  2. 通过调用操作系统Native GUI的API绘制。

服务器

断开TCP连接

  • 根据Connection请求头,如果是keep-alive服务器就保持住tcp连接,如果没有或是close则服务器response传输完后主动关闭tcp连接。
  • 当然现在浏览器都是http1.1都默认是keep-alive的,在浏览器tab关闭时,tcp连接关闭。

Tips

浏览器

查看版本号: chrome://version/
显示性能指标直方图: about:histograms
chrome://histograms/DNS
查看dns缓存: chrome://net-internals/#dns

chrome dns解析

参考文章

How Browsers Work
How Browsers Render Work
Google – Web Performance Best Practices
知乎文章 推荐
腾讯fex文章
伯乐在线文章
CSDN文章1
CSDN文章2
个人网站文章

    原文作者:Robbie丨Yang
    原文地址: https://blog.csdn.net/u013243347/article/details/83270789
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞