从输入 URL 到页面加载完成,中间发生了什么

327 阅读5分钟

分析:从输入 URL 到页面加载完成,中间发生了什么?

  • 根据地址栏输入的地址向DNS查询IP;
  • 通过IP向服务器发起TCP连接;
  • 向服务器发起HTTP请求;
  • 服务器处理请求并返回HTTP报文;
  • 浏览器开始解析渲染页面并显示;
  • 关闭连接;

根据地址栏输入的地址向DNS查询IP(DNS解析)

  • 实现了网址到IP地址的转换;

  • DNS解析是一个递归查询的过程;

  • 所有网址真正的解析过程为: . -> .com -> google.com. -> www.google.com.,对应:本地域名服务器 -> 根域名服务器 -> com顶级域名服务器 -> google.com域名服务器 -> www.google.com的IP地址。

  • DNS缓存;

    DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

  • DNS负载均衡,又叫做DNS重定向。

    DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。

DNS解析全过程

通过IP向服务器发起TCP连接

参考文章:TCP协议详解

涉及知识点:

  • 理解TCP报文格式;

  • 三次握手

  • 为什么一定要进行三次握手呢?

向服务器发起HTTP请求&服务器处理请求并返回HTTP报文;

涉及知识点:

浏览器开始解析渲染页面并显示

至此浏览器已经拿到了一个HTML文档,并为了呈现文档而开始解析。呈现引擎开始工作,基本流程如下(以webkit为例)

  • 通过HTML解析器解析HTML文档,构建一个DOM Tree,同时通过CSS解析器解析HTML中存在的CSS,构建Style Rules,两者结合形成一个Attachment。
  • 通过Attachment构造出一个呈现树(Render Tree)
  • Render Tree构建完毕,进入到布局阶段(layout/reflow),将会为每个阶段分配一个应出现在屏幕上的确切坐标。
  • 最后将全部的节点遍历绘制出来后,一个页面就展现出来了。

从构建DOM树到呈现的过程如下

image

浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。

这个过程比较复杂,涉及到两个概念: DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色、字体等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

image

JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。

浏览器在解析过程中,如果遇到请求外部资源时,如图像、iconfont、JS等。浏览器将重复1-6过程下载该资源。请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。

关闭连接

参考文章:TCP协议详解

涉及知识点:

  • TCP协议关闭连接的四次挥手;
  • 为什么A在TIME-WAIT状态必须等待2MSL时间呢?

参考文章:segmentfault.com/a/119000000…