目录
查阅资料,归纳总结(如有错误可以留言更正哟)
从输入网址到页面加载的整个过程是怎么样的呢?在了解这个问题之前我们先来了解浏览器架构层次,浏览器是多进程架构,在任务管理器(浏览器中按下Shift+Esc)中我们可以看到有浏览器主进程,GPU进程,网络进程,渲染进程,存储进程等等,进程之间的通信使用的是IPC来通信,,这些进程分别都有不同的作用例如:
浏览器主进程主要是负责界面显示,用户交互,子进程管理.渲染进程主要是将HTML,CSS,JS转换成页面,GPU进程用来绘制,网络进程用来负责网络资源的加载等等....
我们从输入网址URL到页面加载的全过程,主要是在浏览器主进程,网络进程,渲染进程中完成的.
一.从输入网址URL到页面加载的全过程
1.在浏览器中输入URL
URL是统一资源定位系统(uniform resource locator)的缩写,为网络地址,俗称网址,用来表示某个资源的地址.
<协议>://<主机名>:<端口>/<路径>/;<参数>?<查询字符串>#<片段(锚)>
用户在输入后浏览器主进程会先判断用户输入的是URL还是关键字,如果是URL就交给我们网络进程了,如果是关键字就会调用我们默认的搜索引擎去合成一个带有搜索关键字的URL.
例如我搜索百度,浏览器判断这个为关键字,就会合成一个带有关键字的URL,例如下图:
合成前
合成后
如果直接就是URL,浏览器会把拿到的URL先进行一个识别,抽取出域名字段,例如.baidu.com
注意:用户按下搜索键并不是直接DNS解析然后发起请求,而是本地查找是否缓存了这个资源,如果发现了这个资源,就会把这个资源返回给浏览器,如果没有发现就进入我们网络请求的流程
2.查找缓存
浏览器先查看浏览器缓存->系统缓存->路由缓存中是否有该地址的网址页面,如果有则显示页面的内容,如果没有则进行下一步
其中:
浏览器缓存指:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求
操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存)
路由器缓存:当上述两个步骤均不能成功获取到DNS记录的时候,会继续搜索路由器缓存
ISP缓存:若上述均失败,继续向ISP搜索
查询系统缓存主要是查询host文件,这个文件主要是保存了以前访问过的网址的域名和IP数据,像一个本地的数据库,如果找到就可以获取本地域名的IP地址,没有找到就会进行路由器缓存
3.DNS域名解析
本地查找没有找到缓存这个资源,浏览器向DNS服务器发起请求,会进行DNS解析,解析该URL中的域名对应的IP地址。
(DNS实际上就是域名和IP对应的数据库,IP地址难以记忆,而机器相互只认识IP地址,于是人们发明了域名,让域名和IP一一对应,它们之间的转换工作我们称之为DNS域名解析.要注意两种方式虽然最后取得的结果一样,但是调用方式不一样,例如IP地址是直接从主机上调用内容,域名是直接通过域名解析服务器指向对应主机的IP地址,再从主机中调用网址的内容)
DNS服务器是基于UDP的,因此会用到UDP协议
。
4.建立TCP连接
解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接,
这时候浏览器就会构建请求行,请求头,Cookies.
5.发起HTTP请求
浏览器发起读取文件的HTTP请求,该请求报文作为TCP三次握手的第三次数据发送给服务器.
TCP三次握手:第一次握手客户端向服务器发送请求,等待服务器的确认,第二次握手就是服务器接收到请求并确认回复一个指令,第三次握手就是客户端收到服务器的指令后返回确认.
6.服务器响应请求并返回结果
服务器对浏览器请求做出响应,并把对应的html文件发送给浏览器
7.关闭TCP连接
通过四次挥手释放TCP连接
8.浏览器渲染
客户端(浏览器)解析HTML内容并渲染出来,浏览器接收到数据包后的解析流程为:
构建DOM树:词法分析然后解析成DOM树(dom tree),是由dom元素及属性节点组成,树的根是document对象
构建CSS规则树:生成CSS规则树(CSS Rule Tree)
构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
布局(Layout):计算出每个节点在屏幕中的位置
绘制(Painting):即遍历render树,并使用UI后端层绘制每个节点。
渲染树和DOM树的区别就是,DOM树完全和html标签一一对应,渲染树会忽略掉不需要的元素,比如head 或者display:none.(注意:visibility:hidden的元素会出现在渲染树中)而且一大段文本中的每一行在渲染树中都是独立的一个节点,渲染树中的每一个节点都存有css属性
9.JS引擎解析过程
调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)
创建window对象:window对象也叫全局执行环境,当页面产生时就被创建,所有的全局变量和函数都属于window的属性和方法,而DOM Tree也会映射在window的doucment对象上。当关闭网页或者关闭浏览器时,全局执行环境会被销毁。
加载文件:完成js引擎分析它的语法与词法是否合法,如果合法进入预编译
预编译:在预编译的过程中,浏览器会寻找全局变量声明,把它作为window的属性加入到window对象中,并给变量赋值为'undefined';寻找全局函数声明,把它作为window的方法加入到window对象中,并将函数体赋值给他(匿名函数是不参与预编译的,因为它是变量)。而变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在。
解释执行:执行到变量就赋值,如果变量没有被定义,也就没有被预编译直接赋值,在ES5非严格模式下这个变量会成为window的一个属性,也就是成为全局变量。string、int这样的值就是直接把值放在变量的存储空间里,object对象就是把指针指向变量的存储空间。函数执行,就将函数的环境推入一个环境的栈中,执行完成后再弹出,控制权交还给之前的环境。JS作用域其实就是这样的执行流机制实现的。