Hotdry.

Article

Nordstjernen 浏览器架构解析:lexbor 与 QuickJS 的轻量级渲染栈

剖析 Nordstjernen 1.0.0 的渲染引擎选型、跨平台 GTK 架构与安全沙箱策略,探讨 88,000 行 C 代码实现现代浏览器的技术取舍。

2026-06-06web

Nordstjernen 浏览器架构解析:lexbor 与 QuickJS 的轻量级渲染栈

2026 年 6 月,挪威开发者 Andreas Røsdal 发布了 Nordstjernen 浏览器 1.0.0 版本。这个从零用 C 语言编写的浏览器项目,以约 88,000 行手写代码(不含 vendored 库)实现了对 HTML Living Standard 第 1-16 章的广泛支持。与 Chromium、Firefox 等动辄千万行代码的庞然大物相比,Nordstjernen 的极简主义路线代表了一种反潮流的浏览器工程哲学:可审计性优先于功能堆砌,标准合规优先于兼容性妥协。

渲染引擎的三件套架构

Nordstjernen 的渲染栈由三个核心组件构成,分别负责解析、执行与绘制:

lexbor:HTML/CSS 解析层

引擎采用 lexbor 作为 HTML5 解析器和 CSS 处理库。lexbor 是一个独立的 C 语言实现,完整实现了 WHATWG 的 tokenization 状态机和树构建算法。在 Nordstjernen 的架构中,lexbor 负责将字节流转换为 DOM 树,并处理 CSS 选择器匹配、级联计算等任务。根据项目文档,HTML 语法解析(§13.2)和片段解析(innerHTML/outerHTML)已完全实现,包括 adoption agency 算法和错误恢复机制。

QuickJS-ng:无 JIT 的 JavaScript 引擎

JavaScript 执行采用 QuickJS-ng 分支的解释器模式,明确禁用 JIT 编译。这一设计决策牺牲了峰值性能,换取了 W^X(Write XOR Execute)内存保护模型的严格保持 —— 代码页不可写,数据页不可执行,从根本上杜绝了 JIT 喷射攻击的内存基础。QuickJS 在 Nordstjernen 中暴露完整的 DOM API,包括 Shadow DOM、Custom Elements、MutationObserver 等现代 Web 组件特性。

Cairo + Pango:绘制与排版

布局计算由 src/layout.c 完成,支持块级 / 行内流、Flexbox、Grid、浮动、定位等现代布局模式。绘制层基于 Cairo 2D 图形库,文本排版通过 Pango 处理,包括复杂脚本的 shaping 和双向文本支持。GTK 4 的 GSK(GTK Scene Graph)渲染器负责最终的 GPU 合成输出。

跨平台架构:GTK 4 的统一抽象

Nordstjernen 的跨平台策略建立在对 GTK 4 的深度依赖之上:

平台 技术栈
Linux GTK 4 + libepoxy + libseccomp
Windows MSYS2 GTK 4 (≥4.22.4)
macOS GTK 4 + Quartz 后端
Android 进行中(android/ 目录)

GTK 4 不仅提供 UI 控件(标签页、书签管理、查找栏等),更重要的是通过 GdkGLContext 统一了 OpenGL 上下文管理,使 WebGL 支持能够以平台无关的方式实现。网络层则统一使用 libcurl,支持 HTTP/2、HSTS、CSP 和分区 Cookie。

这种架构的代价是安装包体积 ——GTK 4 及其依赖(GLib、Pango、Cairo 等)构成了主要的二进制体积来源。但收益是代码复用率极高:核心引擎 src/ 目录下的 93 个 C 文件在所有平台共享同一套实现,仅通过 Meson 构建系统的条件编译处理平台差异(如 Linux 专属的 seccomp 沙箱)。

安全沙箱:纵深防御策略

Nordstjernen 的安全模型采用多层防御:

无 JIT 的内存安全

禁用 JIT 是安全架构的基石。QuickJS 以纯解释模式运行,确保进程内存中不存在动态生成的可执行代码页,配合现代操作系统的 W^X 保护,显著降低了代码注入攻击的可行性。

seccomp/Landlock 系统调用过滤

在 Linux 平台,浏览器利用 libseccomp 安装 seccomp-bpf 过滤器,限制渲染进程可发起的系统调用。同时,项目文档提到 Landlock LSM 的集成计划,用于对文件系统访问进行更细粒度的沙箱控制。值得注意的是,外部媒体播放器(mpv/VLC 等)通过一个预分叉的 broker 进程启动,该进程在沙箱安装前创建,因此播放器以无限制权限运行,而浏览器核心保持受限状态。

WebGL 的显式授权

WebGL 支持默认关闭,首次访问需要用户逐站点显式授权。src/webgl.c 将 WebGL 1/2 API 映射到 OpenGL ES,所有数据传输入口点均进行边界检查和零初始化,降低 GPU 相关攻击面。

工程实践的取舍与启示

Nordstjernen 的设计体现了若干值得关注的工程决策:

代码规模控制

项目将代码可审计性作为核心目标。88,000 行手写 C 代码的规模,使得单个开发者能够在合理时间内通读整个引擎。为实现这一目标,项目明确排除了大量现代 Web 平台的 "标配" 功能:无 Service Workers、无 WebRTC、无 MSE/EME(DRM 媒体)、无 WebGPU。音视频播放完全外包给系统媒体播放器,浏览器本身不链接任何编解码器。

标准优先于兼容性

项目的兼容性文档明确声明:"行为以 spec 文本为准,而非以其他浏览器为准"。这种哲学体现在对 HTML Living Standard 的逐章节跟踪上 —— 文档详细记录了 §1-§16 中 121 个完全实现、57 个部分实现和 4 个缺失的条目。对于现代 Web 的 "移动优先" 现实,Nordstjernen 采用了一种务实的回避策略:对 Facebook、YouTube、Reddit 等重度依赖专有运行时的大型站点,自动重定向到它们的移动版或旧版(如 old.reddit.com),这些版本通常提供更接近标准 HTML 的文档结构。

依赖管理策略

项目采用 "vendored in-tree" 策略处理关键依赖:lexbor、QuickJS-ng 和 Wuffs(Google 的内存安全图像解码库)均以源码形式包含在仓库中,不依赖子模块或外部下载。这既保证了构建的可复现性,也确保了对依赖代码的完全审计能力。系统库(GTK 4、libcurl、SQLite 等)则依赖平台包管理器,但均选择成熟稳定、已广泛审计的组件。

适用场景与局限

Nordstjernen 的架构决定了它并非 Chromium 的通用替代品,而是在特定场景下具有独特优势:

  • 安全敏感环境:无 JIT + seccomp 的架构适合对代码执行有严格限制的场景
  • 嵌入式 / 老旧硬件:解释器模式虽然牺牲性能,但降低了内存和 CPU 需求
  • Web 标准教学 / 研究:可读的代码规模和清晰的模块边界,使其成为理解浏览器引擎工作原理的极佳教材
  • 隐私优先浏览:无遥测、无崩溃报告、无更新检查的设计,配合分区存储和严格的 Cookie 策略

然而,QuickJS 解释器的性能局限意味着重度依赖 JavaScript 的复杂 Web 应用(如 Figma、Notion、Google Docs)运行体验会显著落后于主流浏览器。Web Workers 的部分实现和缺少 SharedArrayBuffer 支持,也限制了其在计算密集型 Web 应用中的可用性。

结语

Nordstjernen 代表了一种浏览器工程的 "极简主义" 路线 —— 在功能完整性与代码可审计性之间,明确选择后者。其技术架构(lexbor + QuickJS + GTK 4)证明了一个观点:现代 Web 标准的核心子集,完全可以在十万行级代码规模内实现。对于追求代码可理解性、安全可审计性或资源效率的场景,这种 "小引擎" 哲学提供了与 "大引擎" 不同的工程选择。


资料来源

  • Nordstjernen GitHub 仓库 README 与架构文档
  • HTML-compatibility.md(1.0.0 版本,2026-06-05)

web

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com