无论是地址栏输入,还有代码里加载的,都会有一个URL,所以加载资源的第一步是 :
- URL解析——(提取出URL包含的信息,比如域名)
- DNS查询——(根据解析出的域名,到DNS服务器上查找该域名对应的IP)
- 请求资源——(带有所有的请求信息,到这个IP地址上去请求资源,然后再从服务器上把请求的资源下载下来)
- 浏览器解析——(浏览器拿到这些资源以后,根据不同的类型,做不同方式的解析)
上边4步就是资源加载的整个过程
一、URL解析
http://www.abc.com:80/get_data.do?productId=1#title
协议://服务器地址:端口号/路径?参数(#title是哈希,是前端页面的锚点,为了标记页面的位置,对于后端来说整个字段一般没什么用)
http
----传输协议www.abc.com
-----域名(对应着服务器上的IP地址)80
----是端口号,如果说域名对应着一个大房子,那么端口号就是门,不同的协议有不同的默认端口,http默认是80端口,https默认是443端口,默认端口号可以省略get_data.do
-----路径,用于在服务器上定位资源?productId=1
-----参数,告诉服务器要什么样子的资源#title
-----哈希,前端页面锚点,用于标记页面位置
二、DNS查询
-
当一个URL被解析之后,我们拿到了一个域名,但是在互联网上,资源都是用IP地址来定位的,所以我们要先做的就是把这个域名转换为对应的IP地址,这就是DNS查询的过程
-
DNS查询里有
两个端
1. 发起请求的浏览器
2. 处理查询请求的DNS服务器
-
试想,如果所有用户请求,都去查询一下DNS服务器,那这个查询量是异常巨大的,再好的DNS服务器也扛不住,所以在在DNS里还有一个很重要的部分,就是
DNS缓存
,用来减少DNS服务器上的查询量
DNS缓存
- 在做DNS查询的时候,浏览器会传过去一个要解析的域名,DNS服务器会查询该域名在服务器上对应的IP地址,当短时间内,再次需要查询这个域名的时候,就会用到DNS缓存,但是缓存是有时间限制的,当过了这个时间,就需要重新到DNS服务器上查询对应的IP了 。
- DNS缓存和DNS服务器组成了整个DNS系统
- DNS缓存是
有很多层的
,浏览器上有,路由器上有,DNS服务器也有,而且根据不同的网络层级
,DNS缓存的时间也不太一样,一般来说,越靠近用户的节点,缓存的时间越短,比如离我们最近的浏览器,它上边DNS缓存的时候一般是1分钟或30秒,DNS根服务器上的缓存时间,最多可以达到10分钟
DNS优化
在前端开发过程中,我们还是有机会对DNS做优化的,那就是 dns-prefetch
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="//cdn.bootcss.com">
<title></title>
</head>
当设置dns-prefetch的时候,页面一开始加载,就会把href对应的域名做DNS查询,然后缓存起来;等到真正请求这些域名下资源的时候,我们就可以省去了DNS查询的时间,提升页面的加载速度
三、资源请求
- 请求的资源,可以是HTML,JS,CSS,或者接口等,可以是通过HTTP请求得来的任何内容;
- 资源请求也有两个角色
-
浏览器
发起请求的时候,浏览器会带着一堆的信息,到后端服务器上寻找资源
请求头里image.png
-
后端服务器
返回的信息包括三部分:
状态码(表示请求是否成功)
响应头(响应的信息,文本长度,缓存时间,压缩方式等)
body响应的内容,如果是image.png
浏览器收到这些响应信息以后,就拿到了自己想要的东西。整个请求的过程就完成了。
-
四、浏览器解析
- 一般最先加载的是HTML文件,在加载HTML文件的时候就开始构建DOM树了,遇到一个HTML节点就把它放入树里,假如我们在加载HTML的时候遇到了一个JS文件,那么构建DOM树的工作就要停下了,先让JS加载和执行,之所以JS有这么高的优先级,是因为它可能操作DOM树,就可能造成之前构建的DOM树白干了,所以,遇到JS先让JS执行,等JS执行完了再进行其他
- 构造DOM树的过程中如果遇到的是style标签,那么就不会造成阻塞了,DOM树的构建和样式的加载会并行往下进行
- DOM树构建完后,就是构建渲染树,渲染树是DOM树和CSS样式表结合的产物,渲染树在不同的浏览器构造的机制不太一样。比如chrome用的webkit内核,是在原来的DOM树上附属一些样式,而Firefox则是根据DOM树和样式表,重新构建出一颗新的渲染树出来。渲染树构建完成以后,每个元素要显示的大小,布局方式也已经确定了。
- 接下来就是根据每个元素的大小和布局方式计算每个元素的实际位置,这就是布局的过程
-
最后一步就是绘制,就是调用浏览器复制显示的部分,将元素安装对应的位置和样式绘制到屏幕上,这样整个浏览器的解析就完成了。
image.png
当然上边是一个比较理想的模型,而实际中,各种浏览器为了优化加载速度,会有更多复杂的处理方式,比如DOM树的构建和渲染树的构建可能是在同时进行,还有的浏览器有预加载的功能,所以在真实场景下都不是按照这个理想的模型就行解析的