# 从输入URL到页面展示的完整过程
# 1. 现代浏览器架构
现代浏览器采用多进程架构模型,以提高稳定性和安全性。以Chrome浏览器为例,主要包括以下进程:
- 浏览器进程:负责浏览器界面显示、用户交互、子进程管理等
- 渲染进程:负责页面渲染,包括HTML解析、CSS样式计算、JavaScript执行等
- 网络进程:负责网络资源加载,处理HTTP请求和响应
- GPU进程:负责图形绘制和硬件加速
- 插件进程:负责运行各种浏览器插件,隔离插件崩溃对浏览器的影响
每个标签页通常会有一个独立的渲染进程,这样即使一个页面崩溃也不会影响其他页面。这种架构设计提高了浏览器的稳定性和安全性。
当我们在浏览器地址栏输入一个URL并按下回车键后,直到页面完全展示在我们面前,这中间经历了哪些步骤呢?这是一个经典的前端面试题,也是理解浏览器工作原理的重要知识点。了解这个过程不仅有助于我们编写更高效的代码,还能帮助我们进行性能优化。
# 2. URL解析与DNS查询
# 2.1 用户输入
用户输入内容,点击回车,这意味着当前页面需要关闭,会调用当前页面的beforeunload事件。此事件使网页能够触发一个确认对话框,询问用户是否真的要离开该页面。如果用户确认,浏览器将导航到新页面,否则导航将会取消;
# 2.2 URL解析
URL(统一资源定位符)是互联网上资源的唯一标识。当用户输入URL后,浏览器首先需要解析URL的各个组成部分:
- 协议(如HTTP、HTTPS)
- 域名(如www.example.com)
- 端口号(如80、443)
- 路径(如/index.html)
- 查询参数(如?name=value)
- 片段标识符(如#section1)
浏览器判断用户输入URL是否合法,如果不合法,则调用默认的搜索引擎,来合成新的带搜索关键字的URL
# 2.3 DNS查询
解析完成后,浏览器需要将域名转换为IP地址,这个过程称为DNS查询。DNS查询的过程如下:
- 浏览器缓存:首先检查浏览器DNS缓存中是否有对应的IP地址
- 系统缓存:检查操作系统hosts文件
- 路由器缓存:查询路由器缓存
- ISP DNS服务器:向本地ISP的DNS服务器查询
- 根DNS服务器:如果本地DNS服务器没有缓存,则向根DNS服务器查询
- 顶级域DNS服务器:根据域名后缀(如.com、.org)查询对应的DNS服务器
- 权威DNS服务器:最终查询到域名对应的IP地址
# 2.4 DNS查询优化建议
- 减少DNS查询次数:合并域名,减少页面中不同域名的资源引用
- DNS预解析:使用
<link rel="dns-prefetch" href="//example.com">标签提前解析域名 - 合理设置DNS缓存时间:通过TTL(Time To Live)控制缓存有效期
# 3. 建立TCP连接
# 3.1 建立TCP连接
获取到服务器IP地址后,浏览器需要与服务器建立TCP连接。这个过程通过TCP三次握手完成:
- 客户端发送SYN包到服务器,请求建立连接
- 服务器回复SYN+ACK包,同意建立连接
- 客户端发送ACK包,确认连接建立
# 3.2 TLS握手过程(HTTPS协议)
如果是HTTPS协议,还需要进行TLS握手来建立安全连接:
- Client Hello:客户端发送支持的TLS版本、加密套件列表和一个随机数
- Server Hello:服务器选择TLS版本和加密套件,并发送服务器证书和另一个随机数
- 证书验证:客户端验证服务器证书的有效性
- 密钥交换:客户端生成预主密钥,使用服务器公钥加密后发送给服务器
- 会话密钥生成:双方使用三个随机数生成会话密钥
- 握手完成:双方交换Finished消息,确认握手完成,开始加密通信
# 4. 发送HTTP请求
TCP连接建立后,浏览器会构建HTTP请求报文并发送给服务器:
- 请求行:包含请求方法、URL、HTTP版本
- 请求头:包含User-Agent、Accept、Cookie等信息
- 请求体:POST等请求方法的数据体
# 5. 服务器处理与响应
# 5.1 资源请求处理
- 网络进程查找浏览器缓存是否存在该资源,如果命中该资源且没有过期,直接返回资源给浏览器进程
- 如果没有命中缓存资源,直接进入网络请求流程
# 5.2 请求处理
服务器接收到请求后进行处理:
- 服务器解析请求,定位资源
- 执行服务端逻辑(如数据库查询、业务处理等)
- 生成响应数据
- 构建HTTP响应报文返回给浏览器
# 6. 浏览器解析与渲染
服务器返回HTML内容后,浏览器开始解析和渲染页面。这个过程称为关键渲染路径(Critical Rendering Path):
# 6.1 DOM树构建
- 字节流转换:浏览器将接收到的HTML字节流转换为字符流
- 词法分析:将字符流转换为Token
- 语法分析:将Token转换为节点对象
- 构建DOM树:将节点对象组织成DOM树结构
# 6.2 CSSOM树构建
- 下载CSS文件:遇到
<link>标签时下载CSS文件 - 解析CSS:将CSS文本解析为样式规则
- 构建CSSOM树:将样式规则组织成CSSOM树结构
# 6.3 JavaScript执行
- 下载JavaScript文件:遇到
<script>标签时下载JS文件 - 解析和编译:将JS代码解析为抽象语法树并编译
- 执行:执行JS代码,可能会修改DOM和CSSOM
# 6.4 渲染树构建
- 从DOM树中筛选出可见节点
- 为每个可见节点匹配对应的CSS样式
- 构建渲染树(Render Tree)
# 6.5 布局计算
- 计算每个渲染对象的几何信息(位置、大小)
- 处理CSS盒模型和定位
# 6.6 绘制
- 将渲染树中的每个节点绘制到屏幕上
- 按照层叠顺序绘制元素
# 6.7 合成
- 将多个图层合成为最终图像
- 利用GPU加速提升性能
# 7. 性能优化建议
为了提升页面加载速度和用户体验,可以从以下几个方面进行优化:
# 7.1 资源优化
- 减少HTTP请求:合并CSS、JavaScript文件,使用CSS Sprites
- 压缩资源:压缩HTML、CSS、JavaScript文件,启用Gzip压缩
- 图片优化:使用适当的图片格式(WebP、AVIF),实施响应式图片
- 字体优化:使用
font-display: swap避免字体加载阻塞渲染
# 7.2 网络优化
- 使用CDN:将静态资源部署到CDN上,减少网络延迟
- 启用缓存:合理设置HTTP缓存头,利用浏览器缓存
- 预加载资源:使用
<link rel="preload">提前加载关键资源 - DNS预解析:使用
<link rel="dns-prefetch">提前解析域名
# 7.3 渲染优化
- 关键资源优化:减少关键资源数量和大小,优化关键路径长度
- CSS优化:将关键CSS内联,非关键CSS异步加载
- JavaScript优化:使用
async或defer属性,避免阻塞HTML解析 - 服务端渲染:对于复杂应用,考虑使用SSR提升首屏渲染速度
# 8. 连接结束
页面渲染完成后,浏览器可能会保持与服务器的连接(HTTP Keep-Alive),以便后续请求复用连接,减少连接建立的开销。
# 9. 参考文章
What happens when you type a URL into your browser? (opens new window)
How Browsers Work: Behind the scenes of modern web browsers (opens new window)
← GET与POST