从输入URL到浏览器显示页面过程中都发生了什么?


URL的输入到浏览器解析的一系列事件

  1. 浏览器根据请求的url交给DNS域名解析
  2. 发起TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 连接结束。

简单说说,浏览器根据请求的url交给dns域名解析,查找真正的ip地址,向服务器发起请求;服务器交给后台处理后,返回数据,浏览器会接收到文件数据,比如,html,js,css,图像等;然后浏览器会对加载到的资源进行语法解析,建立相应的内部数据结构;载入解析到得资源文件,渲染页面,完成显示页面效果。

不够清楚明白吗?

那就再次详细一下,从浏览器接收url,开始进行网络请求线程,发出一个完整的HTTP请求,从服务器端接收请求到对应的后台接收到请求,然后是后台和前台的http交互;其中的缓存问题(http的缓存),浏览器接收到http数据包后的解析流程,css的可视化格式模型,js引擎解析过程等;其他呈现页面效果

这里就需要你对浏览器内核的理解:其中主要的渲染引擎和JS引擎,这里了解一下你对浏览器内核的理解。

  1. 渲染引擎,是负责取得网页的内容,整理信息,以及计算网页的显示方式,然后输出到显示器上。

  2. JS引擎是用于解析和执行javascript来实现网页的动态效果。

浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。其实最开始渲染引擎和JS引擎是没有区分明确的,不过后来JS引擎越来越独立,so,内核就倾向于渲染引擎。

对于资源请求/获取,资源响应/页面渲染,会给网络带宽和设备资源带来压力,这个时候就会考虑到web的性能优化。

通过DNS解析域名的实际IP地址

发送至 DNS 服务器并获得域名对应的 WEB 服务器的 ip 地址。

DNS 解析首先会从你的浏览器的缓存中去寻找是否有这个网址对应的 IP 地址,如果没有就向OS系统的 DNS 缓存中寻找,如果没有就是路由器的 DNS 缓存, 如果没有就是 ISP 的DNS 缓存中寻找。 所以,缓存的寻找过程就是: 浏览器 -> 系统 -> 路由器 -> ISP。 如果在某一个缓存中找到的话,就直接跳到下一步。 如果都没有找到的话,就会向 ISP 或者公共的域名解析服务发起 DNS 查找请求。这个查找的过程还是一个递归查询的过程。

检查浏览器是否有缓存

通过Cache-Control和Expires来检查是否命中强缓存,命中则直接取本地磁盘的html(状态码为200 from disk(or memory) cache,内存or磁盘);

如果没有命中强缓存,则会向服务器发起请求(先进行下一步的TCP连接),服务器通过Etag和Last-Modify来与服务器确认返回的响应是否被更改(协商缓存),若无更改则返回状态码(304 Not Modified),浏览器取本地缓存;

若强缓存和协商缓存都没有命中则返回请求结果。

与 WEB 服务器建立 TCP 连接

TCP 协议通过三次握手建立连接。

客户端通过 SYN 报文段发送连接请求,确定服务端是否开启端口准备连接。状态设置为 SYN_SEND;

服务器如果有开着的端口并且决定接受连接,就会返回一个 SYN+ACK 报文段给客户端,状态设置为 SYN_RECV;

客户端收到服务器的 SYN+ACK 报文段,向服务器发送 ACK 报文段表示确认。此时客户端和服务器都设置为 ESTABLISHED 状态。连接建立,可以开始数据传输了。

翻译成大白话就是:

客户端:你能接收到我的消息吗?

服务端:可以的,那你能接收到我的回复吗?

客户端:可以,那我们开始聊正事吧。

为什么是3次?:避免历史连接,确认客户端发来的请求是这次通信的人。

为什么不是4次?:3次够了第四次浪费

浏览器发送HTTP请求

首先科补一个小知识,HTTP的端口为80/8080,而HTTPS的端口为443

发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由请求行,请求抱头,请求正文组成。

请求行
请求行的格式为Method Request-URL HTTP-Version CRLF eg: GET index.html HTTP/1.1 常用的方法有: GET,POST, PUT, DELETE, OPTIONS, HEAD。

常见的请求方法区别
这里主要展示GET和POST的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Get
GET请求的数据会附加在URL之后,用问号分割,多个参数用&进行连接。

GET请求的数据会暴露在地址栏中。

GET请求URL的编码格式采用的是ASCII编码,而不是Unicode编码。

GET请求传输大小有限制,大小在2KB。

GET相对安全性较差,会被浏览器主动缓存。

GET产生一个TCP数据包,head和data一起发送。

GET浏览器回退无害。
1
2
3
4
5
6
7
8
9
10
POST
POST请求会把数据放置在HTTP请求包的包体中,不会直接暴露给用户。

POST请求,理论上大小是不会限制的,但是实际上各个服务器会规定POST提交数据大小。

POST相对Get更安全,因为参数不会保存浏览器立式或者是web服务器日志中。

POST产生两个TCP数据包,header先发送,服务器响应100ms然后继续,发送data,服务器200然后返回数据。

POST浏览器回退重新请求。

服务器处理请求并返回HTTP报文

它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,分成三份,状态码 ,响应报头和响应报文(你从服务器请求的HTML,CSS,JS文件就放在这里面)

浏览器解析渲染页面

解析HTML形成DOM树

解析CSS形成CSSOM 树

合并DOM树和CSSOM树形成(Render Tree)渲染树

浏览器开始渲染并绘制页面 这个过程涉及两个比较重要的概念回流和重绘,DOM结点都是以盒模型形式存在,需要浏览器去计算位置和宽度等,这个过程就是回流。等到页面的宽高,大小,颜色等属性确定下来后,浏览器开始绘制内容,这个过程叫做重绘。浏览器刚打开页面一定要经过这两个过程的,但是这个过程非常非常非常消耗性能,所以我们应该尽量减少页面的回流和重绘

CSS阻塞情况以及优化

1、style标签中的样式:由HTML解析器进行解析,不会阻塞浏览器渲染(可能会产生“闪屏现象”),不会阻塞DOM解析

2、link引入的CSS样式:由CSS解析器进行解析,阻塞浏览器渲染,会阻塞后面的js语句执行,不阻塞DOM的解析

3、优化:使用CDN节点进行外部资源加速,对CSS进行压缩,优化CSS代码(不要使用太多层选择器)

JS阻塞问题

1、js会阻塞后续DOM的解析,原因是:浏览器不知道后续脚本的内容,如果先去解析了下面的DOM,而随后的js删除了后面所有的DOM,那么浏览器就做了无用功,浏览器无法预估脚本里面具体做了什么操作,例如像document.write这种操作,索性全部停住,等脚本执行完了,浏览器再继续向下解析DOM
2、js会阻塞页面渲染,原因是:js中也可以给DOM设置样式,浏览器等该脚本执行完毕,渲染出一个最终结果,避免做无用功。
3、js会阻塞后续js的执行,原因是维护依赖关系,例如:必须先引入jQuery再引入bootstrap

资源加载阻塞

无论css阻塞,还是js阻塞,都不会阻塞浏览器加载外部资源(图片、视频、样式、脚本等)
原因:浏览器始终处于一种:“先把请求发出去”的工作模式,只要是涉及到网络请求的内容,无论是:图片、样式、脚本,都会先发送请求去获取资源,至于资源到本地之后什么时候用,由浏览器自己协调。这种做法效率很高。

为什么CSS解析顺序从右到左

如果是从左到右的话:

1、第一次从爷节点 -> 子节点 -> 孙节点1
2、第一次从爷节点 -> 子节点 -> 孙节点2
3、第一次从爷节点 -> 子节点 -> 孙节点3

如果三次都匹配不到的话,那至少也得走三次:爷节点 -> 子节点 -> 孙节点,这就做了很多无用功啊

如果是从右到左的话:

1、第一次从孙节点1,找不到,停止
2、第一次从孙节点2,找不到,停止
3、第一次从孙节点3,找不到,停止
这样的话,尽早发现找不到,尽早停止,可以少了很多无用功。

什么是重绘回流

1、重绘:重绘是一个元素外观的改变所触发的浏览器行为,例如改变outline、背景色等属性。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,所以并不一定伴随重排。
2、回流:渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息。计算这些值的过程称为布局或重排,或回流
3、”重绘”不一定需要”重排”,比如改变某个网页元素的颜色,就只会触发”重绘”,不会触发”重排”,因为布局没有改变。
4、”重排”大多数情况下会导致”重绘”,比如改变一个网页元素的位置,就会同时触发”重排”和”重绘”,因为布局改变了。

浏览器缓存分类

强缓存

不会向服务器发送请求,直接从本地缓存中获取数据
请求资源的的状态码为: 200 ok(from memory cache)
优先级:cache-control > expires

协商缓存

向服务器发送请求,服务器会根据请求头的资源判断是否命中协商缓存
如果命中,则返回304状态码通知浏览器从缓存中读取资源
优先级:Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304

参考文章

从浏览器地址栏输入url到显示页面的步骤

URL的输入到浏览器解析的一系列事件
「自我检验」输入URL发生了啥?希望你顺便懂这15个知识点