网页是怎么打开的
这一章有点特殊,围绕一个经典面试题展开。这一个问题涵盖了计算机网络、浏览器、服务器、操作系统等多个方面的知识,所以值得深入研究。
这个面试题是:从输入 URL 到打开网页 ,发生了什么?越详细越好。
- DNS 解析
- TCP 连接(三次握手)
- 发送 HTTP 请求
- 服务器处理请求并返回 HTTP 报文
- 浏览器解析渲染页面(后面细讲)
- 连接结束(四次挥手)
本文将围绕这个问题展开,详细讲述 DNS、Server 以及浏览器的渲染原理。
DNS
输入网址后(你甚至可能还没有点回车),浏览器会先从本地缓存中搜索解析结果。
如果有自然皆大欢喜;如果没有,浏览器就会向 DNS 发送请求。通常,我们使用的是谷歌家的 8.8.8.8. DNS 会把域名解析后的结果返回客户端。
这个解析结果可能是一个 IP 地址,也可能是指向另一个域名,甚至可能是一段文本。
解析类型 | 作用 |
---|---|
A | 指向 IP 地址 |
CNAME | 指向另一个域名 |
TXT | 返回一串文本 |
NS | 返回一个域名服务器 |
如果返回了 IP 地址,浏览器就会向该 ip 地址发出请求,于是就到了我们要谈的 http。
地址栏前面的小锁
如何理解 Https 的工作原理?我们可以用信鸽送信的故事来理解。
小明和小红想用信鸽传一封信。小明把内容写在纸上,再绑在信鸽脚上,让信鸽带给小红。这就是 Http。
如果有中间人拦下了信鸽,就可以自由篡改内容,而小红丝毫不知道被篡改了。如何保护信息安全呢?
小明把信装进一个盒子里,并给他加上锁。小红收到信箱后,将私钥转成公钥,对比信箱上的公钥,如果一致,就可以查看内容。
于是小红小明约定了一个密钥,使用密文传输信息。这样虽然可以防止被篡改,但是不能防止被中间人拦截。
所以如何安全的传输信息呢?
如果引入第三方平台,这个平台大家都信任他。给小明颁发一个凭证,小明先去找第三方验证这个凭证(这样就能防止被中间人拦截)。验证完后用这个凭证给盒子加锁即可。
浏览器渲染
拿到页面的 Document 之后,浏览器会进行以下操作:
- 构建 DOM (文档对象模型)树
- 构建 CSSOM (层叠上下文对象模型)树
- 构建渲染树
- 布局(Layout/Reflow)
- 绘制(Paint)
- 合成(Composite)
DOM 树构建
浏览器将 HTML 解析成树形的数据结构。这个过程是:
- 转换:浏览器从磁盘或网络读取 HTML 的原始字节,根据指定编码(如 UTF-8)将它们转换成字符
- 令牌化:将字符串转换成 W3C 标准规定的各种令牌,如
<html>
、<body>
等 - 词法分析:将令牌转换成对象,定义属性和规则
- DOM 构建:因为 HTML 标记定义不同标签之间的关系,创建的对象会链接在一个树形数据结构中
CSSOM 树构建
CSS 对象模型的构建过程与 DOM 的构建过程类似:
- 浏览器将 CSS 转换成可理解的结构
- 处理所有的 CSS,包括外部 CSS 文件和内联样式
- 确定每个节点的计算样式(Computed Style)
渲染树构建
渲染树(Render Tree)是 DOM 树和 CSSOM 树合并后的结果:
- 从 DOM 树的根节点开始遍历
- 忽略不可见的节点(如 script、meta 标签、display: none 的节点)
- 对每个可见节点,找到适配的 CSSOM 规则并应用
- 输出包含内容和样式的渲染树
布局(Layout)
布局阶段会计算每个节点精确的位置和大小:
- 从渲染树的根节点开始遍历
- 计算每个元素的精确位置和尺寸
- 使用盒模型,将每个节点的位置信息转换为屏幕上的精确像素
绘制(Paint)
绘制阶段会将渲染树中的每个节点转换成屏幕上的实际像素:
- 遍历渲染树
- 创建图层(Layer)
- 填充像素
- 绘制文本、颜色、边框、阴影等视觉效果
合成(Composite)
最后一步是合成阶段:
- 将不同的图层按照正确的顺序合并
- 处理透明度和层叠顺序
- 生成最终的图像呈现给用户
这个过程并非一次性完成。当 DOM 或 CSSOM 被修改时,上述过程需要重复执行,这就是我们常说的重排(reflow)和重绘(repaint)。可以参阅 重排与重绘 一章。