网络请求
从输入 URL 到页面加载完成过程
- 浏览器的地址栏输入 URL 并按下回车。
- 浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期。
- DNS 解析 URL 对应的 IP。
- 根据 IP 建立 TCP 连接(三次握手)
- HTTP 发起请求。
- 服务器处理请求,浏览器接收 HTTP 响应。
- 渲染页面,构建 DOM 树。
- 关闭 TCP 连接(四次挥手)。
针对每一个步骤详细分析
3.DNS解析
在地址栏输入的域名并不是资源所在的真实位置,域名只是 IP 地址的一个映
射。网络服务器的 IP 地址那么多,我们不可能去记一串串数字,因此域名就产生
了.域名解析的过程实际是将域名还原为 IP 地址的过程。
首先浏览器先检查本地 hosts 文件是否有这个网址映射关系,如果有就调用
这个 IP 地址映射,完成域名解析。如果没找到则会查找本地 DNS 解析器缓存,如
果查找到则返回。如果还是没有找到则会查找本地 DNS 服务器,如果查找到则返
回。
最后迭代查询,按根域服务器 ->顶级域,.cn->第二层域,hb.cn ->子域,ww
w.hb.cn
4.TCP连接
在通过 DNS 域名解析后,获取到了服务器的 IP 地址,在获取到 IP 地址后,
便会开始建立一次连接,是由 TCP 协议完成的,主要通过三次握手进行连接。
- 第一次握手:建立连接时,客户端发送 syn 包(syn=j)到服务器,并进入 S
YN_SENT 状态,等待服务器确认; - 第二次握手: 服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自
己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态; - 第三次握手: 客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(a
ck=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED(TCP 连接成功)状
态,完成三次握手
5.HTTP请求
HTTP 请求包含请求起始行、请求头部、请求主体三部分
6.浏览器加载网页
- 浏览器地址 网络请求 服务器返回一个数据包(html文档)
- 浏览器解析运行html代码(此时没有图片,css等外部资源)
- 遇到img标签和src属性会异步的开始请求资源网络请求服务器返回图片编码
- 遇到link-href script-src同样异步加载资源
- url 异步加载资源
- 所有的资源加载完毕了,才会触发window.onload
7.页面的渲染流程
请求网址对应的资源 得到资源 然后运行文档(简单的过程)
浏览器加载html文档是怎么加载到的
- 把标签 文本 注释 属性解析为节点树(DOM Tree)
- 解析DOMtreer中的节点时遇到不同的元素会有不同的操作
- style标签或是link-css遇到css代码 会把css代码解析为css样式结构体
- 遇到src会加载(网络请求)资源
- 把节点树和css样式结构体结合变成呈现树/渲染树
- 按照Render Tree绘制页面
重绘和重流
重绘:按照文档树的解构,重新绘制
回流:页面的元素排版布局数量和节点树中的位置发生改变就是回流
关系:回流一定发生重绘 重绘不一定引起回流
style的易错点
写在style里面的样式,会绘制成css样式结构体,不能用jd.styel.width
来获取
var style1 = document.getComputedStyle(jd)
// style1.width就可以获取
加载对应的业务顺序
脚本的异步加载
-
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
<script defer src="myscript.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
然后从实用角度来说呢,首先把所有脚本都丢到 之前是最佳实践,因为对于旧浏览器来说这是唯一的优化选择,此法可保证非脚本的其他一切元素能预加载和懒加载
8.四次挥手
第一次挥手是浏览器发完数据后,发送 FIN 请求断开连接。
第二次挥手是服务器发送 ACK 表示同意,如果在这一次服务器也发送 FIN 请
求断开连接似乎也没有不妥,但考虑到服务器可能还有数据要发送,所以服务器
发送 FIN 应该放在第三次挥手中。这样浏览器需要返回 ACK 表示同意,也就是第
四次挥手