输入 URL 到页面渲染中间发生了什么?
WEB 应用的生命周期(简述)
- 用户 输入 URL 或者点击链接(DNS 查询)
- 浏览器 生成请求并发送至服务器 (TCP 三次握手四次挥手)
- 服务器 执行某些动作或者获取某些资源;将响应发送至客户端
- 浏览器 处理 Html、CSS、和 JavaScript 并构建结果页面
- 浏览器 监控事件队列 处理事件
- 用户 用户与 web 应用进行交互 期间一直重复 5、6 阶段
- 用户 关闭 web 应用服务
- 生命周期结束
DNS 查询
DNS(互联网域名解析系统,Domain Name System) 的作用是通过域名查询到具体的 IP。
因为 IP 存在数字和英文的组合(IPv6),很不利于人类记忆,所以就出现了域名。你可以把域名看成是某个 IP 的别名,DNS 就是去查询这个别名的真正名称是什么。
在 TCP 握手之前就已经进行了 DNS 查询,这个查询是操作系统自己做的。当你在浏览器中想访问 www.google.com 时,会进行一下操作:
- 操作系统会首先在本地缓存中查询 IP
- 没有的话会去系统配置的 DNS 服务器中查询
- 如果这时候还没得话,会直接去 DNS 根服务器查询,这一步查询会找出负责 com 这个一级域名的服务器
- 然后去该服务器查询 google 这个二级域名
- 接下来三级域名的查询其实是我们配置的,你可以给 www 这个域名配置一个 IP,然后还可以给别的三级域名配置一个 IP
DNS 只有 13 个 IP 地址,但是却有几百上千台服务器,其使用任播(Anycast)技术,因此可以抵抗针对其所进行的分布式拒绝服务攻击(DDoS)。DNS 基于 UDP 协议做查询,至于 DNS 为什么基于 UDP 做查询呢?这特喵的就说来话长了,牵扯到了互联网历史。简单总结下就是 UDP 是来回 2 个包,TCP 是来回至少 7 个包,而 DNS 不是大数据包不需要分包,如果丢包那么就是全部丢包,如果收到了数据,那就是收到了全部数据!所以只需要考虑丢包的情况,那就算是丢包了,重新请求一次就好了。而且 DNS 的报文允许填入序号字段,对于请求报文和其对应的应答报文,这个字段是相同的,通过它可以区分 DNS 应答是对应的哪个请求
DNS 通常是基于 UDP 的,但当数据长度大于 512 字节的时候,为了保证传输质量,就会使用基于 TCP 的实现方式
参考资料
为什么 DNS 适合使用 UDP 协议而不是 TCP 协议?
只有 13 台 DNS 根域名服务器原因
TCP 三次握手四次挥手
待编写…
运行时的页面构建过程
浏览器开始解析文件,如果是 gzip 格式的话会先解压一下,然后通过文件的编码格式知道该如何去解码文件。
文件解码成功后会正式开始渲染流程,先会根据 HTML 构建 DOM 树,有 CSS 的话会去构建 CSSOM 树。如果遇到 script 标签的话,会判断是否存在 async 或者 defer ,前者会并行进行下载并执行 JS,后者会先下载文件,然后等待 HTML 解析完成后顺序执行。
如果以上都没有,就会阻塞住渲染流程直到 JS 执行完毕。遇到文件下载的会去下载文件(img 标签),这里如果使用 HTTP/2 协议的话会极大的提高多图的下载效率。
CSSOM 树和 DOM 树构建完成后会开始生成 Render 树,这一步就是确定页面元素的布局、样式等等诸多方面的东西
在生成 Render 树的过程中,浏览器就开始调用 GPU 绘制,合成图层,将内容显示在屏幕上了。