当在浏览器中输入网址并按下回车后,整个过程大致分为以下几个关键步骤:
1. URL 解析
- 输入处理:浏览器判断输入内容是否为 URL 或搜索关键词。如果是关键词,跳转到默认搜索引擎。
- 协议补全:自动补全协议(如
http://或https://)。 - HSTS 检查:检查网站是否在浏览器的 HSTS(强制 HTTPS)列表中,若是则直接使用 HTTPS。
2. DNS 解析
将域名转换为服务器 IP 地址:
- 浏览器缓存 → 系统缓存(hosts 文件) → 路由器缓存 → ISP 的 DNS 服务器。
- 若未命中缓存,触发 递归查询:
- 根域名服务器 → 顶级域名服务器(如
.com) → 权威域名服务器(如example.com)。
- 根域名服务器 → 顶级域名服务器(如
- 最终获取目标服务器的 IP 地址。
3. 建立 TCP 连接
通过 三次握手 建立可靠连接:
- 客户端发送
SYN包。 - 服务器响应
SYN-ACK包。 - 客户端回复
ACK包,连接建立。
4. TLS 握手(HTTPS 场景)
若使用 HTTPS,需进行加密通信协商:
- Client Hello:客户端支持的 TLS 版本、加密套件、随机数。
- Server Hello:服务器选择的加密套件、随机数、SSL 证书(含公钥)。
- 验证证书:浏览器检查证书有效性(颁发机构、过期时间、域名匹配)。
- 密钥交换:客户端生成预主密钥并用公钥加密发送给服务器。
- 生成会话密钥:双方通过随机数和预主密钥生成对称加密密钥。
5. 发送 HTTP 请求
浏览器发送 HTTP 请求报文:
- 请求行:方法(GET/POST)、路径、协议版本。
- 请求头:
Host、User-Agent、Cookie、Accept-Encoding等。 - 请求体(如 POST 请求)。
6. 服务器处理请求
- 负载均衡:请求可能被转发到集群中的某台服务器。
- 后端处理:执行应用逻辑(如数据库查询、API 调用)。
- 生成响应:返回 HTML、JSON 或其他资源,状态码(如 200 OK、404 Not Found)。
7. 接收响应并解析
浏览器接收响应后:
- 检查状态码:处理重定向(如 301/302)或错误(如 404)。
- 解压缩:处理
gzip或Brotli压缩的内容。 - 缓存策略:根据
Cache-Control、ETag等头部决定是否缓存资源。
8. 渲染页面
关键渲染步骤:
- 构建 DOM 树:
- 解析 HTML 生成树状结构,遇到
<script>会暂停解析并执行(除非标记async/defer)。
- 解析 HTML 生成树状结构,遇到
- 构建 CSSOM 树:
- 解析 CSS 样式(内联、外部、
<style>标签),生成样式规则树。
- 解析 CSS 样式(内联、外部、
- 执行 JavaScript:
- 脚本可能修改 DOM/CSSOM,触发重新解析(
reflow或repaint)。
- 脚本可能修改 DOM/CSSOM,触发重新解析(
- 生成渲染树(Render Tree):
- 合并 DOM 和 CSSOM,排除不可见元素(如
<head>、display: none)。
- 合并 DOM 和 CSSOM,排除不可见元素(如
- 布局(Layout/Reflow):
- 计算每个节点的几何信息(位置、尺寸)。
- 绘制(Paint):
- 将渲染树转换为屏幕上的像素(分层绘制)。
- 合成(Composite):
- 将各图层合并后显示到屏幕上(涉及 GPU 加速)。
9. 加载后续资源
- 图片、字体等异步加载:不会阻塞初始渲染。
- 懒加载内容:按需加载可视区域外的资源。
10. 连接关闭
- 四次挥手 关闭 TCP 连接(或保持 Keep-Alive 复用)。
关键优化点
- 减少 DNS 查询:使用 DNS 预解析(
<link rel="dns-prefetch">)。 - 复用连接:HTTP/2 多路复用、Keep-Alive。
- 资源压缩:Gzip、图片格式优化(WebP)。
- 减少重排/重绘:使用 CSS3 动画、
transform代替布局变更。 - 预加载:
<link rel="preload">提前加载关键资源。