>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
Unknown

深入了解 Chromium 内部机制:为什么普通的 git clone 在这里行不通

Logo

如果你曾经尝试运行 git clone https://github.com/chromium/chromium.git 命令,可能几分钟后就会后悔。仓库已经膨胀到超过 60 GB,而且 README 会用一句简短警告迎接你:不要用普通的 git 来做这件事。

Chromium 是我们电脑上大约一半桌面应用程序的基础。它驱动着 Google Chrome、Microsoft Edge、Brave、Opera、Telegram 桌面客户端、VS Code,以及通过 Electron 运行的 Slack。然而,这个项目的 GitHub 仓库只是 Google 内部基础设施的公开镜像。让我们探索这个庞大项目是如何组织的、如何导航它,以及普通工程师为什么需要打开它的源代码。

为什么标准工作流程在这里行不通

大多数开源项目的设置方式相同:克隆仓库、安装依赖、打开编辑器、提交拉取请求。Chromium 可不会这样。

GitHub 上没有熟悉的 Issues 标签或 Pull Requests 部分。所有开发都通过位于 chromium-review.googlesource.com 的内部 Gerrit 系统进行,bug 则在位于 crbug.com 的专用门户上追踪。

为了将源代码获取到本地机器,项目团队开发了自己的工具集 called depot_tools。其中包含 gclient 工具,用于管理数百个依赖项、第三方库和交叉编译器。仓库本身已经很大了,但加上完整的提交历史、工具链和构建依赖,你需要在快速 SSD 上预留大约 100 GB 的可用空间,以及至少 16 GB 的内存。

# Типичный процесс получения исходников через depot_tools выглядит так
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH="$PATH:/path/to/depot_tools"

mkdir chromium && cd chromium
fetch --nohooks chromium
gclient sync

如果你尝试在典型的四核笔记本电脑上构建整个项目,编译器会让所有核心满载运行数小时。为了加快构建速度,Chromium 工程师使用名为 Reclient 的分布式编译和缓存系统,以及他们自己的构建系统 GN(Generate Ninja)配合 Ninja 使用。

目录结构是如何组织的

当你打开 Chromium 根文件夹时,你的眼睛会开始发晕。里面有数百万行 C++、Rust、Python、Java 和 JavaScript 代码。文档描述了严格的目录组织规则:

  1. src/content — 浏览器核心。这是多进程引擎的实现所在:标签页管理、隔离的渲染沙箱、网络请求处理和安全机制。
  2. src/third_party/blink — 页面渲染引擎(WebKit 的分支)。HTML 和 CSS 规范的实现、DOM 树解析和布局计算都在这里。
  3. src/v8 — JavaScript 和 WebAssembly 引擎。在 Chromium 仓库中,它作为外部依赖项被包含进来。
  4. src/chrome — Chrome 浏览器本身的代码。这包括用户界面、书签、扩展、用户配置文件和设置。

除了这四个主要构建块之外,项目还包含一个 components/ 目录,其中包含可以在不同产品间复用的模块,例如 Android WebView 或 ChromeOS 的 Ash shell。

架构中隐藏着什么有趣的东西

Chromium 不仅作为一个成品浏览器有趣,也是极其复杂的系统架构的典范。代码库中包含着阅读 Web 规范时会产生的问题的答案。

多进程模型和沙箱

浏览器被刻意拆分为隔离的进程。浏览器进程管理窗口和用户输入,网络进程处理资源下载,渲染进程负责页面渲染。

如果某个标签页上的脚本冻结或页面触发严重的内存错误,只有那个特定的渲染进程会崩溃——浏览器继续运行。隔离机制针对每个操作系统分别实现:通过 Linux 命名空间和 seccomp-bpf 系统调用,或 Windows 完整性级别。

通过 Mojo 进行进程间通信

由于浏览器的不同部分生活在隔离的进程中,它们需要一个快速、类型安全的通信机制。Chromium 为此使用 Mojo 系统。

开发者用 .mojom 文件描述接口,代码生成器为 C++、Java 和 JS 创建绑定。这可以防止在不受信任的渲染进程和特权浏览器进程之间传递错误的数据类型。

// Пример описания интерфейса в Mojo
module example.mojom;

interface PingResponder {
  Ping() => (string response);
};

为什么前端和系统开发者应该阅读这个代码

看起来普通 Web 开发者没有理由去深入研究 C++ 源代码。但实际上,Chromium 源代码是关于浏览器如何解释你的页面的最准确的事实来源。

以下是项目的代码库派上用场的四个真实场景:

  • 调试复杂的浏览器 bug。当 CSS Grid 或 Flexbox 在 Chrome 中表现奇怪,但 W3C 规范写得含糊其辞时,你可以打开 src/third_party/blink/renderer/core/layout 中的代码,检查盒子尺寸计算背后的数学原理。
  • 学习 Web API 的工作原理。所有浏览器 JavaScript 方法如 IntersectionObserverWebSocketsServiceWorker 在 Blink 的代码中都有直接对应。通过阅读它们的实现,你可以立即理解哪些操作会产生内存和 CPU 开销。
  • 开发嵌入式浏览器。如果你需要将网页渲染嵌入到自己的 C++ 或 Rust 应用程序中,Chromium Embedded Framework (CEF) 依赖于 src/content 中的公共接口。
  • 寻找高负载系统代码的示例。在这里你可以找到自定义内存分配器(PartitionAlloc)、压缩算法、流式网络协议和加密原语的实现。

从哪里开始学习

如果你只是对浏览源代码感兴趣,不需要占用 100 GB 的磁盘空间。对于代码搜索,项目团队维护了一个名为 Source Search 的优秀 Web 界面,位于 source.chromium.org。它具有即时符号搜索、导航到函数声明以及查看任何文件更改历史的功能。

Chromium 代码库的规模令人望而生畏,但它是业界结构最完善的项目之一。即使只是粗略熟悉 docs/ 目录和 Blink 子系统,也能帮助你更好地理解 Web 平台并编写更优化的前端代码。

相关项目