从输入 URL 到页面展示发生了什么?

这道题考察的不是背诵顺序,而是能否串联浏览器、网络协议、缓存、安全和渲染。回答时先讲主链路,再根据面试官追问展开。

1. 解析 URL 与导航准备

浏览器解析协议、主机、端口、路径、查询参数和片段,并检查:

  • 输入是否是 URL,还是需要交给搜索引擎。
  • HSTS 是否要求把 HTTP 升级为 HTTPS。
  • Service Worker、内存缓存、HTTP 缓存是否可以直接响应。
  • 是否已经存在可复用连接,或是否可以提前做 DNS 预解析、预连接。
  • CSP、混合内容等安全策略是否允许本次导航。

#fragment 通常只在客户端定位,不会发送给服务器。

这里讨论的是一次顶层页面导航。HTML 解析过程中发起的 CSS、JS、图片、字体、接口等子资源请求,会复用类似的缓存、DNS、连接和请求响应链路,但它们还会受到资源优先级、跨域策略、预加载提示和浏览器并发调度影响。

2. DNS 解析

浏览器需要把域名解析成 IP 地址。通常按以下层级查找:

  1. 浏览器和操作系统 DNS 缓存。
  2. hosts 文件。
  3. 本地递归 DNS 服务器。
  4. 根域名、顶级域名、权威 DNS 服务器。

真实系统可能使用 CDN DNS 调度、DoH/DoT 和 Happy Eyeballs,因此“严格逐级请求”只是基础模型。

3. 建立传输连接

HTTP/1.1 与 HTTP/2

如果没有可复用连接,HTTP/1.1 与 HTTP/2 通常先通过 TCP 三次握手建立可靠连接:

客户端 -- SYN --> 服务端
客户端 <-- SYN + ACK -- 服务端
客户端 -- ACK --> 服务端

三次握手的目的不仅是确认双方可达,还要同步初始序列号,避免旧连接报文干扰新连接。

HTTP/1.1 可以使用 Keep-Alive 复用连接,但同一连接上的请求通常仍有顺序限制。HTTP/2 在一条 TCP 连接上多路复用多个 Stream,减少连接数量和应用层队头阻塞,但 TCP 层丢包仍可能影响整条连接。

HTTPS

TCP 建连后进行 TLS 握手:协商协议和密码套件、验证证书、完成密钥交换,随后使用对称加密传输业务数据。

TLS 握手里还可能通过 ALPN 协商使用 HTTP/1.1 还是 HTTP/2;浏览器会校验证书链、域名、有效期和吊销状态等信息。证书异常时,导航可能被拦截在安全警告页。

HTTP/3

HTTP/3 基于 QUIC/UDP,把传输层和 TLS 1.3 握手结合起来,连接恢复时还可能使用 0-RTT。

真实浏览器可能通过 DNS 的 HTTPS/SVCB 记录、Alt-Svc 响应头或历史缓存发现 HTTP/3 可用性。如果 HTTP/3 连接失败,也可能回退到 HTTP/2 或 HTTP/1.1。

4. 发送 HTTP 请求

请求包含:

  • 请求方法、路径和 HTTP 版本。
  • HostAcceptCookieAuthorization、缓存条件等请求头。
  • POST、PUT、PATCH 等请求可能携带请求体。

请求可能先经过浏览器扩展、本地代理、公司网关、负载均衡和 CDN,再到达网关及应用服务器。是否携带 Cookie 取决于 Domain、Path、Secure、SameSite 等属性;跨域子资源请求还会受到 CORS 和凭证模式影响。

5. 服务端与缓存处理

可能出现的分支:

  • CDN 或反向代理直接命中缓存。
  • 服务端鉴权、查询缓存或数据库并生成响应。
  • 条件请求命中后返回 304 Not Modified
  • 页面发生 301302307308 跳转,浏览器重新发起导航。

重定向会重新进入 URL 解析、缓存、DNS 和连接选择流程,但浏览器会限制重定向次数,避免无限跳转。跨站重定向还可能影响 Cookie 发送、Referer 信息和安全策略。

6. 接收并解析响应

浏览器根据状态码和响应头处理缓存、Cookie、内容类型、压缩、重定向和下载行为。HTML 可以边接收边解析,并非必须等待整个文件下载完成。

常见响应头会影响后续行为:

  • Cache-ControlETagLast-Modified 决定缓存和协商缓存。
  • Set-Cookie 写入 Cookie,但会受到 SecureHttpOnlySameSite 等属性限制。
  • Content-Type 决定按 HTML、JSON、图片还是下载处理。
  • Content-Encoding 表示 gzip、br 等压缩编码,需要先解压再解析。
  • Content-Security-PolicyX-Frame-OptionsReferrer-Policy 等安全头影响脚本、嵌入和来源信息。

7. 构建并渲染页面

HTML → DOM ┐
            ├→ Render Tree → Layout → Paint → Composite
CSS  → CSSOM┘

主要步骤:

  1. HTML 解析为 DOM,遇到外部资源会触发请求。
  2. 浏览器的预加载扫描器会提前发现 CSS、JS、图片和字体等资源,并按优先级调度下载。
  3. CSS 解析为 CSSOM;CSS 通常会阻塞渲染树生成。
  4. 普通同步脚本可能阻塞 HTML 解析,deferasync 行为不同。
  5. 字体、图片和视频等资源会影响绘制时机、布局稳定性和用户感知速度。
  6. DOM 与 CSSOM 生成渲染树。
  7. Layout 计算几何位置,Paint 生成绘制指令,Composite 合成图层。

首屏可见不等于页面完全可交互。还要关注 FCP、LCP、INP、CLS 以及框架水合完成时间。

渲染不是只执行一次。JavaScript 修改 DOM 或样式后,浏览器可能重新计算样式、重新布局、重新绘制或只做合成。性能优化里常说的减少重排、减少长任务和使用合成层,本质上都发生在这个阶段。

8. 页面生命周期

  • DOMContentLoaded:DOM 解析完成,延迟脚本执行完成。
  • load:页面依赖的图片、样式等资源基本加载完成。
  • SPA/SSR 应用还可能继续执行 hydration、数据请求、路由初始化和懒加载。
  • 用户交互、定时器、WebSocket、SSE、Service Worker 缓存更新等任务可能在页面展示后持续发生。

一分钟回答模板

浏览器先解析 URL,并检查 HSTS、Service Worker 和缓存;没有命中时通过 DNS 获得 IP。HTTP/1.1 或 HTTP/2 通常先建立 TCP 连接,HTTPS 再完成 TLS 握手,HTTP/3 则基于 QUIC。请求经过 CDN、代理和服务端后返回响应。浏览器可以流式解析 HTML,构建 DOM 和 CSSOM,随后生成渲染树,经历布局、绘制与合成。过程中脚本、样式、缓存策略和框架水合都会影响首屏与可交互时间。

高频追问

  • 为什么 TCP 建连需要三次而不是两次?
  • TLS 如何验证服务器身份?
  • HTTP/2 和 HTTP/3 建连流程有什么区别?
  • CSS 和 JavaScript 分别如何阻塞页面?
  • DOMContentLoadedload 有什么区别?
  • 强缓存和协商缓存在哪一步生效?
  • HTTP/2 多路复用为什么仍可能发生队头阻塞?
  • Service Worker 在这条链路中处于什么位置?