大家好,我是有一点想法的thinkmars,目前在准备面试与工作,借着间隙时间学习复习,写一点基础文章,欢迎想找工作的人与我一起学习,一起讨饭吃~
前言
理解页面加载流程对于性能优化至关重要,前端性能优化无外乎就是优化这个流程。相对底层的协议来说,前端优化的空间比较小,难度较大,而后端服务通信可以选用一些更高效的协议或者自定义协议。前端优化通常集中在建立连接后的阶段,比如缩短传输距离、减少传输次数、减小资源传输体积、降低浏览器渲染压力、使用资源缓存等等。
整个流程大致分为以下步骤:
1. 输入 URL 并解析
- 用户行为:在浏览器地址栏输入
https://www.example.com并按下回车。 - 浏览器解析 URL:
- 检查 URL 的协议(
https)、域名(www.example.com)、端口(默认443)、路径(/)等。 - 如果输入的不是完整的 URL,浏览器会尝试补全(比如自动添加
http://或搜索关键词)。
- 检查 URL 的协议(
2. DNS 域名解析
- 目的:将域名(如
www.example.com)转换成服务器的 IP 地址(如192.0.2.1)。 - 具体步骤:
- 浏览器缓存:检查浏览器是否缓存过该域名的 IP。
- 系统缓存:查询本地 hosts 文件或操作系统缓存。
- 路由器缓存:检查路由器 DNS 缓存。
- ISP DNS 服务器:向互联网服务提供商(如电信、联通)的 DNS 服务器发起请求。
- 递归查询:如果 ISP 的 DNS 没有缓存,会从根域名服务器(
.)开始逐级查询:- 根域名服务器 →
.com顶级域名服务器 →example.com权威域名服务器。
- 根域名服务器 →
- 返回 IP:最终获得
www.example.com对应的 IP 地址。
graph TD
A[浏览器缓存] --> B[系统缓存]
B --> C[路由器缓存]
C --> D[ISP DNS服务器]
D --> E[根域名服务器]
E --> F[顶级域名服务器]
F --> G[权威域名服务器]
G --> H[返回IP地址]
3. 建立 TCP 连接(三次握手)
- 目的:浏览器和服务器通过 TCP 协议建立可靠连接。
- 三次握手过程:
- 浏览器 → 服务器:发送
SYN=1, Seq=x(同步请求)。 - 服务器 → 浏览器:回复
SYN=1, ACK=x+1, Seq=y(确认并同步)。 - 浏览器 → 服务器:发送
ACK=y+1(最终确认)。
- 浏览器 → 服务器:发送
- 结果:连接建立,可以传输数据。
graph LR
A[浏览器] -- SYN=1,Seq=x --> B[服务器]
B -- SYN=1,ACK=x+1,Seq=y --> A
A -- ACK=y+1 --> B
4. 发送 HTTP 请求
- 浏览器构造 HTTP 请求,例如:
GET / HTTP/1.1 Host: www.example.com User-Agent: Chrome/... Accept: text/html, */* - 如果是 HTTPS:
- 先进行 TLS 握手(交换密钥、验证证书)。
- 加密后续通信内容。
5. 服务器处理请求
- Web 服务器(如 Nginx/Apache):
- 解析请求路径,可能转发给后端应用(如 PHP、Node.js)。
- 后端应用:
- 处理业务逻辑(如查询数据库)。
- 生成 HTML 响应(或 JSON 数据)。
6. 服务器返回 HTTP 响应
-
响应示例:
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1234 <!DOCTYPE html> <html>...</html> -
状态码:
200表示成功,404表示页面不存在等。
7. 浏览器解析和渲染页面
- 解析 HTML:构建 DOM 树(文档对象模型)。
- 解析 CSS:构建 CSSOM 树(CSS 样式规则)。
- 合并为渲染树:结合 DOM 和 CSSOM,排除不可见元素(如
<head>)。 - 布局(Layout):计算每个元素的位置和大小。
- 绘制(Paint):将像素点绘制到屏幕上。
- 执行 JavaScript:
- 如果遇到
<script>标签,会暂停 HTML 解析,先执行 JS(除非标记为async或defer)。
- 如果遇到
graph TD
A[解析HTML] --> B[构建DOM树]
B --> C[解析CSS]
C --> D[构建CSSOM树]
D --> E[合并渲染树]
E --> F[布局计算]
F --> G[绘制页面]
G --> H[执行JavaScript]
H -->|遇到<script>| I[暂停HTML解析]
I --> J[执行JS代码]
J -->|完成| K[继续HTML解析]
8. 加载静态资源
- 页面中可能包含图片、CSS、JS 等资源,浏览器会再次发起请求获取它们(可能并行下载)。
9. 关闭 TCP 连接(四次挥手)
- 目的:数据传输完成后释放连接。
- 四次挥手过程:
- 浏览器 → 服务器:发送
FIN=1(请求关闭)。 - 服务器 → 浏览器:回复
ACK(确认收到)。 - 服务器 → 浏览器:发送
FIN=1(服务器也准备关闭)。 - 浏览器 → 服务器:回复
ACK(最终确认)。
- 浏览器 → 服务器:发送
graph LR
A[浏览器] -- FIN=1 --> B[服务器]
B -- ACK --> A
B -- FIN=1 --> A
A -- ACK --> B
完整流程图
graph TD
A[输入URL] --> B[DNS解析]
B --> C[TCP三次握手]
C --> D[发送HTTP请求]
D --> E[服务器处理请求]
E --> F[返回HTTP响应]
F --> G[浏览器解析渲染]
G --> H[加载静态资源]
H --> I[TCP四次挥手]
关键点总结
- DNS 解析:把域名变成 IP 地址。
- TCP 握手:确保可靠传输。
- HTTP 请求/响应:获取网页内容。
- 渲染引擎:将 HTML/CSS/JS 变成可视化页面。
如此复杂的流程,跑完也不过秒级甚至毫秒级,不得不感叹网络技术的神奇。当然,这也得益于硬件技术与软件工程的进步。