阅读,与值得关注的内容Readance

近7W颗星!真正的独立浏览器开源引擎

项目简介

Ladybird[1] 是一款真正独立的网页浏览器,采用基于 Web 标准的全新引擎。

目标是打造一款完整、可用、面向现代 Web 的浏览器,而 不是 Chromium / WebKit / Gecko 的移植。 代码体量大约与 Servo 同级,约为 WebKit C++ 的 1/15、Gecko 的 1/20、Chromium 的 1/50。当前仍是 pre-alpha

Ladybird 采用多进程架构,包含一个主 UI 进程、若干 WebContent 渲染进程、一个 ImageDecoder 进程,以及一个 RequestServer 进程。

图像解码和网络连接在独立进程中完成,以提高对恶意内容的鲁棒性。每个标签页都有自己的渲染进程,并与系统其余部分隔离(沙箱化)。

目前,许多核心库支持组件继承自 SerenityOS:

  • LibWeb:网页渲染引擎
  • LibJS:JavaScript 引擎
  • LibWasm:WebAssembly 实现
  • LibCrypto / LibTLS:密码学原语与传输层安全(TLS)
  • LibHTTP:HTTP/1.1 客户端
  • LibGfx:2D 图形库、图像解码与渲染
  • LibUnicode:Unicode 与区域设置支持
  • LibMedia:音频与视频播放
  • LibCore:事件循环、操作系统抽象层
  • LibIPC:进程间通信

Ladybird 的关键技术原理可以概括成一句话:按 Web 标准从零实现引擎,用多进程把“不可信网页”与 UI/网络/解码隔离开,用多棵树把页面从 HTML 变成像素。 下面按分层把源码结构对应到设计原则。


关键技术

目录
职责
AK/
自研基础库:容器、智能指针、ErrorOr、字符串
Libraries/
LibWeb / LibJS / LibGfx / LibIPC / LibCore / LibMedia …
Services/WebContent
RequestServerImageDecoderWebWorker
UI/
Qt / AppKit 等平台 UI
Documentation/
进程模型、渲染管线、IDL、媒体管线

进程模型:把攻击面切到进程边界

设计目标不是“快”,而是 面对任意(可能恶意)网页时的稳定与隔离。下面是其进程模型的示意图:

┌────────────── Browser / UI 进程 ──────────────┐
│  Qt / AppKit / GTK                            │
│  LibWebView::Application                      │
│    设置、书签、Cookie、历史、进程生命周期          │
│    每个标签一个 ViewImplementation ──IPC──┐     │
└──────────────────────────────────────────│────┘
                                           │
        ┌──────────────┬───────────────────┴──────────────┐
        ▼              ▼                                  ▼
┌─────────────┐  ┌─────────────┐                   ┌─────────────┐
│ WebContent  │  │ WebContent  │   …每标签/站点一份 │ WebContent  │
│ LibWeb+LibJS│  │             │                   │             │
│ 无直接网络   │  │             │                   │             │
└──────┬──────┘  └──────┬──────┘                   └──────┬──────┘
       │                │                                 │
       ▼                ▼                                 ▼
┌─────────────┐                                  ┌─────────────┐
│RequestServer│  HTTP/HTTPS/WebSocket/缓存/TLS   │ImageDecoder │
└─────────────┘                                  └─────────────┘

关键隔离点:

  1. 每标签一个 WebContent:HTML/CSS/JS/布局/绘制都在这里。崩溃只死一个标签。跨源导航可再开新进程(站点隔离方向)。
  2. 网络不在渲染进程:WebContent 只能经 RequestServer 出门。DNS、HTTP、TLS、磁盘缓存都在网络进程。
  3. 解码不在渲染进程:图片历史上是内存破坏高发区,解码在强沙箱的 ImageDecoder,成功才回传 bitmap。
  4. WebWorker 单独进程:后台脚本与页面主世界隔离。
  5. 沙箱:文档描述 pledge() / unveil();Linux 侧还有 seccomp 一类限制。除 UI 进程外,辅助进程以非登录用户跑。

库分层

依赖方向大致是:

UI / LibWebView
      ↓
   LibWeb  ←—— LibJS ← LibGC ← AK
      ↓
 LibGfx / LibURL / LibIPC / LibMedia / LibHTTP / LibTLS
      ↓
      AK

原则上每个进程只链它该有的库。RequestServer 不链 LibWeb;ImageDecoder 不跑 JS。AK 相当于项目自己的 STL 风格基础层。

LibWeb 内部再按 规范名分子目录 + 命名空间

  • Libraries/LibWeb/HTML/ → Web::HTML
  • Libraries/LibWeb/DOM/ → Web::DOM
  • Libraries/LibWeb/CSS/Fetch/SVG/WebGL/ …

找实现就按规范找目录,这是刻意的可导航性。


4. LibWeb 渲染管线

这是整台引擎最核心的技术原理。

URL
 │  IPC
 ▼
RequestServer 拉字节
 │
 ▼
HTMLParser ──► DOM 树
CSSParser  ──► CSSOM(变量先保持 unresolved)
LibJS      ──► 脚本可 document.write 回灌解析器
 │
 ▼
StyleComputer
  选择器从右向左匹配
  按 origin(UA → author)+ specificity + !important 层叠
  在 cascade 阶段解析 custom property
  ──► StyleProperties / ComputedProperties
 │
 ▼
TreeBuilder ──► Layout 树(CSS 盒树的 C++ 化)
  display:none 不生成节点
  匿名盒修复:块/行级孩子混排、残缺 table、list-item marker
 │
 ▼
FormattingContext 递归排版(从 ICB / 视口开始)
  BFC / IFC / TFC / FFC / GFC + 自研 SVGFormattingContext
  产出 LayoutState(used values);可 commit 或丢弃(不可变测量)
 │
 ▼
Paintable 树 ──► 层叠上下文
  按 CSS2 附录 E 分相位绘制:背景 → 边框 → float → 前景文字 → outline → overlay
 │
 ▼
DisplayList 记录绘制命令
DisplayListPlayerSkia 在渲染线程用 Skia(Vulkan/Metal/CPU)回放
共享 backing store 交给 Browser 进程上屏

项目地址

https://github.com/LadybirdBrowser/ladybird


感谢阅读。如果本文对你有帮助,欢迎点赞、在看,或转发给需要的朋友。


参考资料

[1] 

Ladybirdhttps://ladybird.org/


前往微信阅读全文

内容来自公众号,可前往微信查看原文。

查看作者的更多文章 →