这是一个老生常谈的问题,面试的过程中也经常被问到,因为这个有很多可以挖掘的点,今天来做一个总结,方便查看。
1、在浏览器地址栏输入URL地址,并验证URL合法性
2、浏览器查看缓存
1、如果资源没有缓存,则发起请求
2、如果已经缓存,并且时效可用,则直接提供给客户端跳转到解码(步骤15),否则与服务器进行验证
3、检验是否可用一般可以设置http头的两个属性 Expires 和 Cache-Control
3、浏览器解析URL获取协议、主机、端口、path
4、浏览器组装一个http(直接访问地址相当于get请求)请求报文
5、浏览器获取主机IP过程如下:
1、浏览器缓存
2、本级缓存
3、hosts文件
4、路由器缓存
5、ISP DNS缓存
6、DNS递归查询,就近分配。由于可能存在负载均衡策略,所以每次的ip可能并不一致
6、打开一个socket与目标地址连接,建立TCP链接,三次握手
1、客户端发送一个SYN=1,Seq=X的包到服务器
2、服务器发回SYN=1,ACK=X+1,Seq=X的响应
3、客户端发送ACK=Y+1,Seq=Z的响应包
注: 之所以有第三次,是因为如果第一次请求因为某个网络节点而延迟,那么客户端会重新发起一次请求,但是假定第一次的请求在延迟后最终到达,那么服务端会以为这是一个正常的请求,发回响应后便一直等待,但是此时客户端并没有请求或者请求已经完成了,服务器端就会这么一直傻等着,浪费服务器资源
如图:
7、TCP链接建立后发送https请求
8、服务器接受请求并解析,将请求转发到服务程序,如虚拟主机使用HTTP Host头部判断请求的服务程序
9、服务器检查HTTP请求头是够包含魂村验证信息如果验证缓存没过时效,返回304等对应状态码
10、处理程序处理对http请求作出响应
11、服务器将相应报文通过TCP连接发送回浏览器
12、浏览器接收http相应,并根据情况来决定关闭TCP连接,还是保留重用。关闭TCP连接的四次挥手如下:
1. 主动⽅发送Fin=1, Ack=Z, Seq= X报⽂
2. 被动⽅发送ACK=X+1, Seq=Z报⽂
3. 被动⽅发送Fin=1, ACK=X, Seq=Y报⽂
4. 主动⽅发送ACK=Y, Seq=X报⽂
13、浏览器检查相应状态码,并作出对应的反应
14、如果资源可用,进行缓存
15、对相应进行解码(诸如gzip等压缩文件等)
16、根据资源类型决定如何处理(假定资源为HTML文档)
17、解析HTML文档,构建DOM树,构建CSSOM树,执行JS脚本,这些没有严格的顺序,根据实际情况来
1、构建DOM树
1). Tokenizing,令牌化,根据html规范将字符解析成各种令牌,每个令牌都有自己的属性及规则
2). 词法分析:将令牌转换成对象并定义属性及规则
3). DOM构建:根据HTML标记关系将词法分析后的对象组成DOM树
2、构建CSSOM树过程基本与DOM树一致
3、js脚本的加载具体可以根据defer、async等进行控制
注: 如果不设置这两个属性,则会同步加载执行,阻塞后面的渲染,如果设置了async,则加载和 渲染 后续文档元素的过程和js脚本的加载执行并行进行(异步)。如果设置了defer,则加载后续文档元素的过程和js脚本的加载执行并行进行(异步),但是脚本执行要在所有元素解析完成后,DOMContentLoaded事件触发之前完成。如图:benngbung同步
18、DOM树和CSSOM树合并构建渲染树
1、从DOM树的根节点遍历所有可见节点,不可见节点包括:
1).script,meta这种本身就不可见标签
2).对每一个可见节点,找到恰当的CSSOM规则并应用
3).发布可视节点的内容和计算样式
19、js脚本解析
1、浏览器创建document并解析html,将解析后的文本和元素节点添加到document中,此时,document.readystate为loading
2、HTML解析器遇到同步的脚本(无defer和async)时,将他们添加到文档中,然后执行行内或者外部脚本。脚本会同步执行,
并且在脚本下载和执行的时候,解析器暂停。这样就可以用document.write()把文本插入到输入流中。同步脚本经常简单定义函数
和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容
3、当解析器遇到设置async属性的script时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但解析器不会停下。
异步脚本禁止使用document.write(),他们可以访问自己script和之前的文档元素
4、当文档解析完成,document.readyState变成interactive
5、所有的defer脚本会按照文档出现的顺序执行,延迟脚本能访问完整文档树,不适宜再使用document.write(),可以操作DOM。
6、浏览器在Document对象上触发DOMContentLoaded事件
7、文档解析完成,浏览器可能还在等待图片等加载,等这些内容完成载入并且所有异步脚本完成载入和执行后,
document.readystate变成coplete,window触发load事件
显示页面
html在解析的过程中会逐步显示页面,当DOM树和CSSOM树合并渲染树的时候,会先进行布局计算,然后调用GPU,合成图层,然后显示
以上就是输入地址到显示页面的过程,在浏览器的展示范畴,还有很多概念值得去深入研究,比如当页面上元素的宽、高等属性发声了变化,会引起浏览器的重排,之后浏览器会再次渲染,叫做重绘,但是当文字的颜色发生变化,那么不引起页面布局的重排,但是会引起页面重新渲染,叫做重绘。
浏览器本身的刷新频率按照1秒钟60次刷新,对应的浏览器提供的API为 window.requestAnimationFrame,可以使用这个作为回调来执行动画 window.requestAnimationFrame(function(){})。
合理的利用API,可以帮助我们提高用户体验,下一篇讲讲如何提高下性能