Chromiumの内部を覗いてみる:なぜ通常のgit cloneが通用しないのか

もしgit cloneコマンドを試みたことがあるなら、おそらく数分で後悔したでしょう。リポジトリは60ギガバイト以上に膨れ上がっており、READMEには簡潔な警告が書かれています:通常のgitでは行わないでください。
Chromiumは、私たちのコンピュータのデスクトップアプリケーションの半分以上の基盤となっています。Google Chrome、Microsoft Edge、Brave、Opera、Telegramデスクトップクライアント、VS Code、Slack(Electron経由)を動かしています。しかし、このプロジェクトのGitHubリポジトリは、Googleの内部インフラストラクチャの公開ミラーにすぎません。この巨大なプロジェクトがどのように構成されているか、どうナビゲートするか、なぜ普通のエンジニアがソースコードを開く必要があるのかを探ってみましょう。
なぜ標準的なワークフローがここで機能しないのか
ほとんどのオープンソースプロジェクトは同じように設定されています:リポジトリをクローンし、依存関係をインストールし、エディタを開いて、プルリクエストを作成します。Chromiumではそれは通用しません。
GitHubにはおなじみのIssuesタブやPull Requestsセクションはありません。すべての開発は内部のGerritシステムで行われ、バグは専用のポータルで追跡されます。
ソースコードをローカルマシンに取得するために、プロジェクトチームはdepot_toolsという独自のユーティリティセットを開発しました。その中に含まれているのは、数百の依存関係、サードパーティライブラリ、クロスコンパイラを管理するgclientツールです。リポジトリ自体は巨大ですが、完全なコミット履歴、ツールチェーン、ビルド依存関係を含めると、高速なSSDに約100ギガバイトの空き容量と少なくとも16ギガバイトのRAMが必要です。
典型的なクアッドコアラップトップでプロジェクト全体をビルドしようとすると、コンパイラは数時間にわたってすべてのコアを最大にします。ビルドを高速化するために、ChromiumエンジニアはReclientという分散コンパイルとキャッシュシステムを使用し、独自のビルドシステムGN(Generate Ninja)とNinjaを組み合わせて使用します。
ディレクトリ構造の構成
Chromiumのルートフォルダを開くと、目まいがします。C++、Rust、Python、Java、JavaScriptで数百万行のコードが含まれています。ドキュメントにはディレクトリ構成の厳格なルールが記載されています:
- content — ブラウザコア。マルチプロセスエンジンが実装されている場所で、タブ管理、分離されたレンダリングサンドボックス、ネットワークリクエスト処理、セキュリティメカニズムが含まれます。
- third_party/blink — ページレンダリングエンジン(WebKitのフォーク)。HTMLとCSS仕様の実装、DOMツリーのパース、レイアウト計算が含まれています。
- v8 — JavaScriptとWebAssemblyエンジン。Chromiumリポジトリでは外部依存関係として含まれています。
- chrome — Chromeブラウザ本身的コード。ユーザーインターフェース、ブックマーク、エクステンション、ユーザープロファイル、設定が含まれます。
この4つの主要なビルディングブロックに加えて、プロジェクトにはcomponentsディレクトリがあり、Android WebViewやChromeOS用のAshシェルなど、異なる製品間で再利用可能なモジュールが含まれています。
アーキテクチャに隠された興味深い点
Chromiumは完成したブラウザとしてだけでなく、信じられないほど複雑なシステムアーキテクチャの例としても興味深いです。コードベースには、ウェブ仕様を読んでいるときに浮かんでくる疑問への答えが含まれています。
マルチプロセスモデルとサンドボックス
ブラウザは意図的に分離されたプロセスに分割されています。Browser Processはウィンドウとユーザー入力を管理し、Network Processはリソースのダウンロードを処理し、Renderer Processはページをレンダリングします。
タブ上のスクリプトがフリーズしたり、ページが致命的なメモリエラーを発生させたりしても、特定のrendererプロセスだけがクラッシュし、ブラウザは動作し続けます。分離メカニズムは、Linuxの名前空間とseccomp-bpfシステムコール、またはWindowsの整合性レベルを通じて、各オペレーティングシステム向けに個別に実装されています。
Mojoを通じたプロセス間通信
ブラウザの異なる部分が分離されたプロセスに存在するため、高速で型安全な通信メカニズムが必要です。ChromiumはこれにMojoシステムを使用しています。
開発者は.mojomファイルでインターフェースを記述し、コードジェネレーターがC++、Java、JSのバインディングを生成します。これにより、信頼されていないrendererプロセスと特権を持つbrowserプロセスの間で誤ったデータ型が渡されることを防ぎます。
フロントエンド開発者とシステムエンジニアがこのコードを読むべき理由
普通のウェブ開発者がC++のソースコードを掘り下げる理由がないと思うかもしれません。しかし実際には、Chromiumのソースコードは、ブラウザがページをどのように解釈するかについての最も正確な真実の源です。
プロジェクトのコードベースが役立つ4つの実際のシナリオがあります:
- 複雑なブラウザバグのデバッグ。CSS GridやFlexboxがChromeで奇妙な動作をするが、W3C仕様が曖昧に書かれている場合、third_party/blinkのレンダリングコードを開いてボックスサイズ計算の数学を調べることができます。
- Web APIの動作を学ぶ。fetch()、requestAnimationFrame()、createImageBitmap()などのすべてのブラウザJavaScriptメソッドは、Blinkのコードに直接対応しています。実装を読むことで、どの操作がメモリとCPUのオーバーヘッドを作成するかすぐに理解できます。
- 組込みブラウザの開発。独自のC++やRustアプリケーションにウェブページのレンダリングを埋め込む必要がある場合、Chromium Embedded Framework(CEF)はcomponents/cef_publicの公開インターフェースに依存しています。
- 高負荷システムコードの例を見つける。ここでは、カスタムメモリアロケーター(PartitionAlloc)、圧縮アルゴリズム、ストリーミングネットワークプロトコル、暗号プリミティブの実装が見つかります。
学習の始め方
単にソースコードを閲覧感兴趣であれば、100ギガバイトのディスク容量を費やす必要はありません。コード検索のために、プロジェクトチームはSource Searchという優れたウェブインターフェースを保守しています。インスタントシンボル検索、関数宣言へのナビゲーション、任意のファイルの変更履歴の表示機能が含まれています。
Chromiumのコードベースは規模において威圧的ですが、業界で最も構造化されたプロジェクトの1つです。componentsディレクトリやBlinkサブシステムに触れるだけでも、ウェブプラットフォームをより深く理解し、より最適化されたフロントエンドコードを書くのに役立ちます。
関連プロジェクト