老生常谈之从输入URL到页面呈现的过程(全)

简介: 面试中经常会遇到这个问题,简述从输入URL到页面呈现的过程,根据应试者的经验,理解程度不同,答案也是五花八门,下面说说我自己的理解。

面试中经常会遇到这个问题,简述从输入URL到页面呈现的过程,根据应试者的经验,理解程度不同,答案也是五花八门,下面说说我自己的理解。

目录

我们将这个过程分为以下几个过程

  1. DNS查询
  2. TCP连接
  3. SSL/TLS 握手
  4. 请求报文
  5. 响应报文
  6. 页面构建渲染
  7. JS代码执行

1. DNS查询

DNS查询的细节可以参考 DNS查询原理

在互联网中的不同主机是通过 IP 来标识的,IP 就相当于网络资源的门牌号一样,帮助我们寻找网络资源的所在主机。但是为了记忆的便利,我们在浏览网站时一般是输入我们熟悉的域名(www.baidu.com),那么如何通过域名来寻找对应 IP 呢?于是出现了域名系统(Domain Name System)。

域名系统(Domain Name System DNS)是互联网的一项服务。它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。

117.png


我们在浏览器输入一个新网址时候,可能会经历以下几个步骤

  1. 浏览器查询(浏览器DNS缓存)
  2. 本地HOST文件查询(系统级DNS缓存)
  3. local DNS Servr(运营商DNS查询服务)

我们常说的 CDN 也是在这一过程实现的,大概就是通过全局流量管理(GTM)为我们分配合适的 CDN Server

在运营商DNS查询服务中,如果运营商本地没有对应的缓存的话,需要经历 根域名服务(.) -> 顶级域名服务(.com) -> 本地域名服务(.baidu)

115.png


2. TCP连接

TCP相关的知识可以参考 TCP/IP简记


TCP 处于传输层,其位于网络层(IP)的上一层,在通过 IP 寻找到对应的主机后,就要进行 TCP 连接了。

TCP 连接需要发送三次数据包发送来确定连接,我们称之为三次握手。

114.png

  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
  • 第二次握手:服务器端接收到数据包后由标志位SYN=1知道客户端请求建立连接,服务端将标志位SYN和ACK都设置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
  • 第三次握手:客户端接收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1。

3. TLS/SSL四次握手

关于 TLS/SSL 协议是如何建立连接的,可以参考阮一峰大神的文章,写的非常棒 图解SSL/TLS协议

我们都知道,在使用 HTTP 协议时,因为采用的是明文传输的方式,所以会有以下风险

  1. 窃听风险,第三方可以获知通信内容
  2. 篡改风险,第三方可以修改通信内容
  3. 冒充风险,第三方可以冒充他人身份参与通信

所以现在我们引入了 HTTPS 协议来防止以上风险,而 HTTPS 其实就是 HTTP + SSL 的结合,其重点在于如何建立 SSL 连接。

建立 SSL 连接,其原理在于服务端提供数字证书和证书中的公钥(通过数字证书认证来确认公钥来自服务端),使用非对称加密通信

113.png


使用非对称加密会有个问题,因为算法原理,非对称加密计算量大,当数据量大时,计算耗时且耗性能。所以引入对称加密,对后面的数据传输采用对称加密,非对称加密主要用于生成对称加密的对称密钥。

所以建立 SSL 协议有以下过程

  1. 客户端向服务端获取公钥
  2. 双方协商生成对称密钥
  3. 使用对称密钥进行加密通信

现在我们来看看 SSL 连接的四次握手


112.png

  1. 客户端给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。
  2. 服务端确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。
  3. 客户端确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给服务端,同时根据三个随机数生成对称密钥。客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供服务器校验。
  4. 服务端使用自己的私钥,获取客户端发来的随机数(即Premaster secret),同时根据三个随机数生成对称密钥。服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

为什么需要三个随机数?

  1. 使用随机数生成密钥可以保证每次生成的密钥不同,增加密钥安全性。
  2. SSL 协议不信任每个主机能生成完全随机的随机数,所以通过客户端和服务端生成的三次(伪)随机数生成接近完全随机数的随机数。

SSL

SSL详细分为四个阶段,SSL/TLS协议详解

4. 发起请求

当和资源主机建立了 TCP SSL 连接之后,便发起 HTTP 请求。请求这块其实没啥好说的,主要是需要了解下浏览器的缓存策略。通常在服务端我们会设置 HTML 文档的响应头 Cache-Control: no-cache 以便页面不会被强缓存。

关于浏览器缓存可以参考我之前的文章 浏览器缓存机制

5. 响应请求

服务端根据请求资源地址返回客户端需要的页面内容,这一步没什么好说的。

6. 页面构建渲染

浏览器获取到页面内容后,便开始解析页面。从这一步开始,就是浏览器解析渲染的舞台了。


111.png

①. DOM解析(文档对象模型)

首先是 html 标签经过 HTML Parser 解析成 DOM Tree,我们称之为 DOM 树,它是一个页面的框架骨骼。

②. CSS解析

样式经过 CSS Parser 解析为 Style Rules(也可叫做 CSSOM)。css 的解析和 DOM Tree 的构建是并行的。

③. DOM Tree + Style Rules => Render Tree

DOM Tree 和 Style Rules 准备好之后,并会根据 css 规则将 DOM Tree 和 Style Rules 结合成 Render Tree(渲染树)。

④. Layout(布局)

Render Tree 构建好之后开始计算节点的位置,大小,也就是不同节点的布局。这步确定页面节点的展示位置,也就是页面的展示框架。

当首次布局计算完成后,后因元素大小,位置等变化引起自身或其它节点的布局改变,我们称之为回流(重排)

⑤. Painting(绘制)

布局计算完成之后,便开始为节点“着色”,将节点的相关样式通过像素填充展现在屏幕上。

当节点的非布局样式改变(如背景颜色),则会重新触发绘制,我们称之为重绘(重新绘制),当然,回流也会引起重绘。

⑥. Display


在 Painting 结束后,其实节点就已经在页面显示了,我们就可以看到一个渲染完成的页面了。

如果严谨的说,这中间还有个合成的过程,不同的渲染层合成为一个合成层,对应图形层。合成层也可能含有多个,例如我们常说的3d硬件加速就是这个原理,通过创建新的合成层,避免引起其它元素的回流重绘,额外的合成层可能导致内容占用,所以也不能滥用。

关于渲染合成的细节可以参考其它大佬的文章 浏览器层合成与页面渲染优化


7. JS执行


在页面解析中遇到 JS 标签时会立即执行,此时 DOM Tree 的构建被阻塞,所以当遇到外联的 JS (非异步)时也会等待 JS 的下载执行后再继续解析 DOM。

重点看看两个事件节点


  • DOMContentLoaded


当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

需要注意的是,外联的 JS 是会阻塞 html 解析的,所以会影响 DOMContentLoaded 的执行


  • load


当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发 load 事件。它与 DOMContentLoaded 不同之处在于,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。


总结


断断续续写了快一周终于结束了,写着写着就是越来越没有耐心。本来想重点写页面渲染过程的,但是没有写好,可能是自身的理解还不够。不管怎样,尽力而为,问心无愧。还有一些东西没有说清楚,可能后面会在其它文章中单独介绍。


  • 硬件加速原理

  • 页面的渲染合成原理

  • CSS/JS对应页面解析的阻塞

参考

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
2天前
|
缓存 网络协议 前端开发
URL输入到页面渲染过程详解
URL输入到页面渲染过程详解
13 1
|
2天前
|
JavaScript
如何在JS中实现修改URL参数而不刷新页面
如何在JS中实现修改URL参数而不刷新页面
|
2天前
|
JavaScript
js如何实现修改URL参数并不刷新页面
js如何实现修改URL参数并不刷新页面
|
2天前
|
存储 小程序
【边做边学】uni.switchTab的目标页面获取不到url携的参数
【边做边学】uni.switchTab的目标页面获取不到url携的参数
|
2天前
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
|
2天前
|
JavaScript 前端开发 UED
如何在JS中实现修改URL参数而不刷新页面
如何在JS中实现修改URL参数而不刷新页面
56 2
|
2天前
|
Web App开发 缓存 网络协议
|
2天前
uView queryParams 对象转URL参数
uView queryParams 对象转URL参数
17 0
|
2天前
|
JavaScript
vue截取URL中的参数
vue截取URL中的参数
21 0
|
2天前
|
前端开发
[牛客网-前端大挑战QD2] 获取url参数
[牛客网-前端大挑战QD2] 获取url参数
22 0