Web 浏览器的工作原理 - 解析 HTML(第 3 部分,附插图)📜🔥

2025-06-04

Web 浏览器的工作原理 - 解析 HTML(第 3 部分,附插图)📜🔥

到目前为止,我们讨论了navigationdata fetching。今天我们将讨论parsing一般和HTML parsing具体。

3. HTML解析

我们看到,在向服务器发出初始请求后,浏览器会收到一个响应,其中包含HTML我们尝试访问的网页资源(第一个数据块)。现在,浏览器的工作就是启动parsing数据。

Parsing means analyzing and converting a program into an internal format that a runtime environment can actually run

换句话说,解析意味着将我们编写的文本代码(HTML、CSS)转换为浏览器可以处理的内容。这parsing将由(不要与浏览器的browser engine混淆)完成。Javascript engine

browser engine是每个主流浏览器的核心组件,其主要作用是整合结构(HTML)和样式(CSS),以便在屏幕上绘制网页。它还负责找出哪些代码片段是可交互的。我们不应该将它视为一个独立的软件,而应该将其视为一个更大软件(在我们这里指的是浏览器)的一部分。

目前有许多浏览器引擎,但大多数浏览器使用以下三个积极开发的完整引擎之一:

Gecko
由 Mozilla 为 Firefox 开发。它曾支持其他多款浏览器,但目前除了 Firefox,Tor 和 Waterfox 仍在使用 Gecko。它使用 编写C++ and JavaScript,自 2016 年起,还支持Rust

WebKit
它主要由 Apple 为 Safari 开发。它也支持 GNOME Web(Epiphany)和 Otter。(令人惊讶的是,在 iOS 上,包括 Firefox 和 Chrome 在内的所有浏览器也都基于 WebKit。)它用 编写C++

Blink 是 Chromium 的一部分,
最初是 WebKit 的一个分支,主要由 Google 为 Chrome 浏览器开发。它还支持 Edge、Brave、Silk、Vivaldi、Opera 以及大多数其他浏览器项目(部分通过 QtWebEngine 实现)。它使用 编写C++

现在我们知道了谁会执行这个操作parsing,让我们看看从服务器接收到第一个 HTML 文档后究竟会发生什么。假设文档如下所示:



<!doctype HTML>
<html>
 <head>
  <title>This is my page</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <h1>This is my page</h1>
  <h3>This is a H3 header.</h3>
  <p>This is a paragraph.</p>
  <p>This is another paragraph,</p>
</body>
</html>


Enter fullscreen mode Exit fullscreen mode

即使请求页面的 HTML 大于初始 14KB 数据包,浏览器也会开始解析并尝试根据其拥有的数据呈现体验。HTML parsing涉及两个步骤:tokenizationtree construction(构建称为的东西DOM Tree (Document Object Model))。

标记化

It is the lexical analysis and it converts some input into tokens (basic components of source code). Imagine we would take an English text and break it down into words, where the words would be the tokens.

标记化过程结束时的结果是一系列零个或多个以下标记:DOCTYPE、开始标记(<tag>)、结束标记(</tag>)、自闭合标记(<tag/>)、属性名称、值、注释、字符、文件结束或元素内的纯文本内容。

图片描述

构建 DOM

第一个 token 创建后,tree building开始执行。这本质上是tree like structure基于先前解析的 token 创建一个(称为文档对象模型)。

DOM 树描述了 HTML 文档的内容。<html>元素是文档树的第一个标签和根节点。树反映了不同标签之间的关系和层次结构。我们有嵌套parent nodes在其他标签中的标签,以及嵌套在其他标签中的标签child nodes。节点数量越多,构建 DOM 树所需的时间就越长。以下是我们从服务器获取的 HTML 文档示例的 DOM 树:

图片描述

实际上,DOM 比我们在该模式中看到的要复杂得多,但为了更好地理解,我将其保持简单(此外,我们将在以后的文章中更详细地讨论 DOM 及其重要性)。

这个构建阶段是reentrant,这意味着在处理一个 token 时,tokenizer 可能会被恢复,从而导致在第一个 token 处理完成之前,其他 token 会被发出并处理。从字节到 DOM 创建,完整的过程如下所示:

图片描述

解析器逐行执行,从上到下。当解析器遇到非阻塞资源(例如图片)时,浏览器会从服务器请求这些图片并继续解析。另一方面,如果遇到阻塞资源(CSS 样式表、添加到<head>HTML 部分中的 JavaScript 文件或从 CDN 添加的字体),解析器将停止执行,直到所有阻塞资源下载完毕。因此,如果您使用 JavaScript,建议将<script>标签添加到 HTML 文件的末尾;或者,如果您想将它们保留在<head>标签中,则应为其添加deferasync属性(async允许在脚本下载完成后立即异步执行,并defer仅在解析完整个文档后才允许执行)。

预加载器和加快页面加载速度

Internet Explorer、WebKit 和 Mozilla 都在 2008 年实现了预加载器,作为处理阻塞资源(尤其是脚本)的一种方式(我们之前说过,当遇到脚本标签时,HTML 解析将停止,直到脚本下载并执行完毕)。

使用 时pre-loader,当浏览器卡在脚本上时,第二个更轻量的解析器会扫描 HTML 以查找需要检索的资源(样式表、脚本等)。然后,预加载器开始在后台检索这些资源,目的是确保当主 HTML 解析器到达时,这些资源可能已经下载完毕(如果这些资源已被缓存,则跳过此步骤)。

参考资料:

文章来源:https://dev.to/arikaturika/how-web-browsers-work-parsing-the-html-part-3-with-illustrations-45fi
PREV
Web 浏览器的工作原理 - 获取数据(第 2 部分,附插图)🚀
NEXT
如何在 JavaScript 中使用 Object.freeze()