1. 输入网址 → 浏览器解析与缓存检查
你在地址栏输入 www.example.com
并回车后,浏览器首先做两件事:
解析网址:判断协议(默认
http
或https
)、域名(www.example.com
)、路径(如/page
)等。检查缓存:先查本地是否有该网址的缓存(包括 HTML、CSS、JS、图片等资源)。如果有且未过期(通过
Cache-Control
或Expires
头判断),直接使用缓存,跳过后续网络请求(节省时间)。
例子:你昨天访问过 www.example.com
,今天再次输入,若缓存未过期,浏览器直接从本地读取页面显示。
2. DNS 解析:域名 → IP 地址
如果缓存中没有,浏览器需要找到 www.example.com
对应的服务器 IP 地址(如 192.168.1.1
),这一步叫 DNS 解析。流程类似“查电话簿”:
本地 DNS 缓存:先查浏览器/操作系统的本地 DNS 缓存(可能存过该域名的 IP)。
递归查询:若本地没有,浏览器向本地 DNS 服务器(如运营商提供的)发起请求。本地 DNS 服务器若也没有,会递归查询:
根域名服务器(全球 13 台,如
a.root-servers.net
):告诉本地 DNS“负责.com
的顶级域名服务器(TLD)地址”。顶级域名服务器(TLD)(如
.com
的服务器):告诉本地 DNS“example.com
的权威 DNS 服务器地址”。权威 DNS 服务器(
example.com
的官方服务器):返回www.example.com
对应的 IP 地址(如93.184.216.34
)。
缓存结果:本地 DNS 服务器会将结果缓存,方便后续请求;浏览器也会缓存 IP,减少重复查询。
关键:DNS 解析可能耗时几十到几百毫秒,所以现代浏览器会并行查询(如预解析链接中的域名)。
3. 建立 TCP 连接(三次握手)
拿到服务器 IP 后,浏览器通过 TCP 协议与服务器建立可靠连接。TCP 是“可靠的快递员”,需要先“确认对方在线”:
第一次握手:浏览器发送一个 TCP 包(
SYN=1
),告诉服务器“我想和你建立连接”。第二次握手:服务器回复(
SYN=1, ACK=1
),表示“收到你的请求,我也想连接”。第三次握手:浏览器再回复(
ACK=1
),表示“收到你的确认,连接建立成功”。
注意:如果是 HTTPS(https://www.example.com
),在 TCP 连接建立后,还需要进行 TLS 握手(协商加密算法、交换密钥),确保后续数据加密传输(防止被窃听)。
4. 发送 HTTP 请求
TCP 连接建立后,浏览器向服务器发送 HTTP 请求(如 GET /page HTTP/1.1
),请求内容包括:
请求行:方法(
GET
/POST
)、路径(/page
)、协议版本(HTTP/1.1
)。请求头:浏览器信息(
User-Agent
)、接受的响应格式(Accept
)、Cookies(Cookie
)、缓存策略(If-None-Match
)等。请求体:如果是
POST
请求,会附带表单数据或 JSON(如登录时提交的用户名密码)。
例子:你访问 www.example.com/login
并提交表单,浏览器会发送 POST
请求,请求体包含 username=admin&password=123
。
5. 服务器处理请求并返回响应
服务器收到 HTTP 请求后,根据路径(如 /page
)和参数(如查询字符串 ?id=1
),调用后端程序处理:
静态资源(如 HTML、CSS、图片):直接读取服务器文件,返回给浏览器。
动态资源(如用户登录、数据查询):后端代码(如 Java/Python/Node.js)执行逻辑(查数据库、调用接口),生成动态内容(如 HTML 模板填充数据)。
处理完成后,服务器返回 HTTP 响应,包含:
状态码:表示请求结果(
200 OK
成功,404 Not Found
资源不存在,500 Internal Error
服务器错误)。响应头:内容类型(
Content-Type: text/html
)、缓存策略(Cache-Control
)、服务器信息(Server: Nginx
)等。响应体:实际内容(如 HTML 代码、JSON 数据、图片二进制流)。
例子:请求 www.example.com
返回 200 OK
,响应体是 HTML 代码 <html><body>Hello World</body></html>
。
6. 浏览器解析与渲染页面
浏览器收到响应后,开始“翻译”HTML 并显示页面,核心步骤是 构建 DOM 树 → 构建 CSSOM 树 → 合并渲染树 → 布局 → 绘制:
(1)解析 HTML,构建 DOM 树
浏览器从 HTML 第一行开始解析,将标签(如 <div>
, <p>
)转换为树状结构的 DOM 树(Document Object Model),每个节点代表一个 HTML 元素。
注意:遇到 <script>
标签时,默认会阻塞渲染(防止 JS 修改 DOM 导致布局错乱),直到 JS 执行完毕(除非用 async
或 defer
标记)。
(2)解析 CSS,构建 CSSOM 树
同时,浏览器解析 CSS(内联/外部样式表),将样式规则(如 color: red
、width: 100px
)转换为 CSSOM 树(CSS Object Model),描述每个 DOM 节点的样式。
(3)合并 DOM 和 CSSOM,生成渲染树(Render Tree)
将 DOM 树和 CSSOM 树合并,生成 渲染树(仅包含可见元素,如排除 display: none
的节点)。
(4)计算布局(Layout)
渲染树中每个节点需要确定位置和大小(如 div
在屏幕左上角,宽度 300px),这一步叫“布局”或“重排”(Reflow)。
(5)绘制(Paint)
根据布局结果,将每个节点的颜色、边框、阴影等视觉属性填充到屏幕像素中,这一步叫“绘制”或“重绘”(Repaint)。
例子:一个 <div style="color:red; width:100px;">Hello</div>
会被解析为 DOM 节点,结合 CSSOM 中的 color:red
和 width:100px
,最终在屏幕上显示红色、宽 100px 的“Hello”文字。
7. 页面显示完成,后续交互
渲染完成后,页面正式显示在屏幕上。此时浏览器还会:
执行 JS:如果页面中有 JS 代码(如
script
标签),会触发事件(如onclick
)、操作 DOM(如动态添加元素)。监听事件:等待用户交互(如点击链接、滚动页面),触发新的 HTTP 请求或 JS 逻辑。
例子:页面上的“提交”按钮绑定了 JS 事件,点击后会发送 POST
请求到服务器,重复上述流程(DNS 解析→TCP 连接→发送请求→接收响应→重新渲染部分页面)。
总结流程图
输入网址 → 缓存检查 → DNS 解析(域名→IP) → TCP 连接(三次握手) → 发送 HTTP 请求 → 服务器处理并返回响应 → 浏览器解析渲染(DOM/CSSOM→渲染树→布局→绘制) → 显示页面 → 后续交互。
整个过程通常需要 几百毫秒到几秒(取决于网络速度、服务器性能、页面复杂度),优化关键步骤(如减少 DNS 查询、压缩资源、使用 CDN)可显著提升加载速度。