独立开发者两年从零造浏览器,成功通过Acid3测试

一个人从零构建的浏览器引擎
在浏览器引擎被 Chromium(Blink)、Firefox(Gecko)和 Safari(WebKit)三大巨头垄断的今天,一位独立开发者在 Hacker News 上发布了一条引人瞩目的动态:他花费两年时间从零开发一款全新浏览器,终于通过了经典的 Acid3 兼容性测试。
当前全球浏览器市场的引擎层面实际上只剩三个独立实现:Google 主导的 Blink(从 WebKit 分叉而来,用于 Chrome、Edge、Opera 等)、Mozilla 的 Gecko(用于 Firefox)、以及 Apple 的 WebKit(用于 Safari 及所有 iOS 浏览器)。这种局面被称为"引擎单一化"危机——据 StatCounter 数据,基于 Blink 的浏览器已占据全球超过 75% 的市场份额。这意味着 Google 对 Web 标准的演进方向拥有事实上的否决权,任何一个新 CSS 特性或 JavaScript API,如果 Blink 不实现,就很难成为事实标准。这种权力集中让许多 Web 标准制定者和开源倡导者深感忧虑。
当前的三引擎格局并非一直如此。在 2000 年代中期,活跃的浏览器引擎至少有五个:Trident(Internet Explorer)、Gecko(Firefox)、WebKit(Safari)、Presto(Opera)和 KHTML(Konqueror)。转折点始于 2013 年,Opera 放弃自研的 Presto 引擎转投 Chromium 阵营;同年 Google 从 WebKit 分叉出 Blink。2015 年 Microsoft 宣布用 EdgeHTML 替代 Trident,但到 2018 年又宣布放弃 EdgeHTML 转用 Chromium。每一次独立引擎的消亡都加剧了生态集中化。这种演变的根本原因在于 Web 标准的爆炸性增长——维护一个跟上标准演进的渲染引擎每年需要数亿美元的投入,这使得没有强大商业模式支撑的独立引擎难以为继。
这条 "Show HN" 帖子虽然目前热度不算爆炸(17 个赞、7 条评论),但它触及了一个被反复讨论的话题:在现代 Web 标准如此庞杂的背景下,一个人还有没有可能造出一款可用的浏览器?答案显然是肯定的——尽管过程无比艰辛。

Acid3 测试到底考了什么
对于不太熟悉的读者,Acid3 是由 Web Standards Project 于 2008 年发布的一套浏览器兼容性测试。它包含 100 项子测试,全面检验浏览器对 DOM Level 2、DOM Level 3、CSS3 选择器、SVG、ECMAScript、HTTP 缓存等核心 Web 标准的支持程度。
Acid 测试系列由 Web Standards Project(WaSP)组织发起,旨在推动浏览器厂商遵循 W3C 标准。Acid1(1998年)专注 CSS1 的盒模型渲染;Acid2(2005年)扩展到 CSS2.1、PNG 透明度和 HTML 表格渲染,其标志性的"笑脸"图案成为 Web 开发史上的经典符号;Acid3(2008年)则是最为复杂的一版,它不仅测试静态渲染,还通过 JavaScript 动态生成测试用例,检验 DOM 操作的正确性和性能。值得注意的是,Acid3 的设计者 Ian Hickson 后来成为 HTML5 规范的主要编辑,这体现了标准推动者和测试设计者之间的紧密联系。
其中,DOM Level 2(2000年发布)引入了事件模型(包括事件捕获和冒泡机制)、样式操作接口、文档遍历和 Range 操作等关键能力,是现代 JavaScript 交互式 Web 应用的基石。DOM Level 3(2004年)进一步增加了文档加载/保存、XPath 支持、键盘事件规范化等功能。正确实现这两个级别的 DOM 规范意味着浏览器引擎能够支持绝大多数 JavaScript 库和框架(如 jQuery、React 等)所依赖的底层 DOM 操作。
ECMAScript 测试的技术深度
Acid3 测试中的 ECMAScript 部分不仅检验基本的 JavaScript 语法支持,还测试了 ES3/ES4 时代讨论的一些高级特性,包括正确的原型链行为、闭包作用域、异常处理机制、正则表达式引擎的规范一致性等。JavaScript 引擎的实现需要处理该语言特有的复杂语义——如动态类型转换规则(著名的"类型强制转换表")、this 绑定的多种模式、属性访问的原型链查找等。一个符合规范的 JavaScript 引擎还必须正确实现垃圾回收机制,处理循环引用、弱引用等内存管理问题,这对个人开发者是相当大的工程挑战。
HTTP 缓存测试的技术含义
Acid3 中包含的 HTTP 缓存测试验证浏览器是否正确遵循 HTTP 协议的缓存语义。这包括对 Cache-Control 头部各指令(max-age、no-cache、no-store、must-revalidate 等)的正确解释、ETag 和 Last-Modified 条件请求的处理、以及 Vary 头部对缓存键的影响等。正确实现 HTTP 缓存不仅是标准兼容性问题,更直接影响 Web 应用性能——据统计,合理的浏览器缓存可以减少 40-60% 的网络请求。这要求浏览器引擎维护一个符合规范的缓存存储层,正确处理缓存过期、验证和淘汰策略。
CSS3 选择器与 SVG 的测试深度
Acid3 测试中对 CSS3 选择器的检验涵盖了属性选择器、伪类(如 :nth-child、:not)、伪元素、组合选择器等数十种语法形式。CSS3 选择器引擎是浏览器样式计算的核心组件——当一个页面包含数千个 DOM 节点和数百条 CSS 规则时,选择器匹配的效率直接决定了页面渲染性能。现代浏览器通常采用从右向左的匹配策略和布隆过滤器等优化技术来加速这一过程。SVG(可缩放矢量图形)则是 Acid3 中另一个重要测试维度,它要求浏览器能正确解析和渲染基于 XML 的矢量图形语法,包括路径、变换、滤镜等复杂特性,这对浏览器的图形子系统提出了很高要求。
曾经的行业分水岭
在 2008 年前后,Acid3 曾是各大浏览器厂商竞相攻克的标杆。能否拿到满分(100/100)并正确渲染参考图形,一度是衡量浏览器引擎成熟度的重要指标。Safari、Chrome、Opera 等主流浏览器为此展开了激烈的"军备竞赛"。
虽然如今 Acid3 早已无法覆盖现代 Web 的全部复杂性——HTML5、WebAssembly、各种新 CSS 特性等都不在其测试范围内——但它仍然是一个极具象征意义的里程碑。对于一款从零开始、由个人独立开发的浏览器而言,通过 Acid3 意味着其引擎已经具备了相当扎实的标准兼容基础,尤其在 DOM 操作、CSS 选择器解析和 JavaScript 引擎方面。
为什么自研浏览器引擎值得关注
浏览器引擎的超高开发门槛
现代浏览器是软件工程中最复杂的产物之一。它需要 HTML 解析器、CSS 布局引擎、JavaScript 运行时、网络栈、渲染管线、安全沙箱等众多子系统协同工作。以 Chromium 项目为例,其背后有数千名工程师和 Google 的巨额投入,代码量高达数千万行。
HTML 解析器的实现复杂度
HTML 解析是浏览器引擎最基础也最棘手的环节之一。与 XML 不同,HTML 的解析规则允许大量的容错行为——未闭合的标签、错误嵌套、隐式元素生成等都有明确的处理算法。HTML5 规范中的解析算法(即 "tree construction" 算法)定义了超过 80 种不同的插入模式和数百条处理规则,包括 foster parenting(表格中错误放置内容的重新定位)、自动闭合(如 <p> 标签遇到块级元素时自动闭合)等边缘情况。这套算法的复杂度远超一般的编译器前端,是从零实现浏览器的第一道重大工程挑战。
CSS 布局引擎的工程挑战
CSS 布局引擎负责将 DOM 树和样式规则转化为屏幕上像素的精确位置。现代 CSS 包含多种布局模式:传统的块级布局(Block Flow)、行内布局(Inline Layout)、浮动与清除(Float/Clear)、Flexbox 弹性布局、Grid 网格布局,以及绝对/固定定位等。每种布局模式都有独立的规范文档,仅 CSS2.1 的视觉格式化模型就有数百页的精确描述。更大的挑战在于这些布局模式之间的交互——当一个 Flex 容器包含浮动元素和绝对定位子元素时,布局计算需要处理大量的边缘情况和规范中的模糊地带。
渲染管线与合成器架构
现代浏览器的渲染管线远比"解析-布局-绘制"的简化模型复杂。完整的渲染流程包括:样式计算(Style Recalc)→ 布局(Layout)→ 分层(Layer Tree Construction)→ 绘制记录(Paint Recording)→ 光栅化(Rasterization)→ 合成(Compositing)→ 显示(Display)。其中,合成器(Compositor)架构是实现流畅滚动和 CSS 动画的关键——它允许某些视觉变化(如 transform、opacity)绑在独立的合成层上处理,无需重新布局或绘制,直接在 GPU 上完成变换。Chrome 的合成器运行在独立线程中,即使主线程被 JavaScript 阻塞,页面滚动仍能保持 60fps 的流畅度。
正因如此,近年来除了少数如 Ladybird(由 SerenityOS 创始人 Andreas Kling 主导)这样的独立浏览器项目外,几乎没有全新的浏览器引擎从零诞生。绝大多数所谓"新浏览器"(如 Arc、Brave)实质上都是基于 Chromium 内核的套壳定制产品。
Ladybird 是目前最受关注的独立浏览器引擎项目之一。它最初是 Andreas Kling 为其业余操作系统项目 SerenityOS 编写的浏览器组件,后于 2024 年正式宣布独立为跨平台浏览器项目。Ladybird 使用 C++ 编写,拥有自研的 LibWeb 渲染引擎和 LibJS JavaScript 引擎。该项目在 2024 年获得了包括 GitHub 联合创始人 Chris Wanstrath 在内的投资者 100 万美元资助,并组建了小型全职团队。Ladybird 的发展轨迹说明,独立浏览器引擎虽然起步于个人项目,但在获得社区关注后有可能演化为更大规模的协作工程。
除 Ladybird 外,近年来还涌现了多个值得关注的独立浏览器引擎尝试。Servo 是由 Mozilla Research 发起、现由 Linux Foundation 托管的实验性引擎,使用 Rust 语言编写,探索并行渲染和内存安全;Flow Browser 是一个使用 Zig 语言编写的轻量级浏览器;Kosmonaut 是一个教育目的的 Rust 浏览器引擎。在更早期,还有 Dillo(C 语言的极简浏览器)和 NetSurf(C 语言,面向嵌入式和老旧硬件)等项目。这些项目共同构成了浏览器引擎多样性的生态图谱,每个项目都在不同维度上挑战着"浏览器只能由大公司开发"的假设。
独立造轮子的技术价值
一个人在两年内让自研引擎通过 Acid3,无论这个项目最终能否走向实用,其技术意义和教育价值都不容小觑。它至少证明了三件事:
- Web 标准可被个人系统性实现:虽然规范庞杂,但核心部分的工程量并非不可逾越
- 垄断领域仍有探索空间:独立开发者依然能在巨头把持的赛道中做出有意义的技术贡献
- 绝佳的深度学习路径:从零构建浏览器是理解 DOM 模型、渲染流程、JS 引擎等底层原理的最佳方式之一
从零实现 JavaScript 引擎的技术路径
独立开发者自研 JavaScript 引擎通常有几种可选路径:完全从零手写(如 Ladybird 的 LibJS)、嵌入现有引擎(如 V8 或 SpiderMonkey)、或使用较轻量的嵌入式引擎(如 QuickJS、Duktape)。完全自研意味着需要实现词法分析器、语法解析器(处理 JavaScript 特有的自动分号插入等规则)、AST 构建、字节码生成、解释器或编译器后端,以及符合规范的内置对象库(包括数百个内置方法)。仅 ES2023 规范的正式文档就有近 900 页,加上各种附录和 Web 兼容性要求,工作量极为可观。选择哪种路径取决于项目目标:如果重点在渲染引擎的实现学习,嵌入 V8 是务实的选择;如果追求完全独立和深度理解,从零实现则是更纯粹的技术挑战。
通过 Acid3 之后的挑战与现实
需要冷静看待的是,通过 Acid3 距离"日常可用的浏览器"仍有巨大鸿沟。现代网站大量依赖 HTML5 API、复杂的 JavaScript 框架、WebGL 渲染、视频编解码,以及各类安全与性能优化机制。要让自研引擎流畅打开主流网站,所需的工作量往往是通过 Acid3 的数十倍甚至上百倍。
Web 标准的规模与演进速度
从零实现浏览器引擎面对的不仅是技术复杂度,还有标准本身的庞大规模和持续膨胀。据估计,如果将所有相关 Web 标准规范打印出来,篇幅将超过 10 万页。仅 CSS 一项就包含 70 多个独立的规范模块(从 CSS Color Level 4 到 CSS Containment),而 Web API 的数量已超过 1000 个。更具挑战的是,W3C 和 WHATWG 的规范持续更新——HTML Living Standard 采用持续演进模式而非版本发布,这意味着浏览器引擎需要不断追踪标准变化。对于个人开发者而言,确定"实现哪些标准"和"实现到什么程度"是一个关键的范围管理决策。
现代浏览器引擎的兼容性评估已从 Acid3 转向 Web Platform Tests(WPT) 项目。WPT 是由各浏览器厂商共同维护的测试套件,包含超过 170 万个独立测试用例,覆盖 HTML、CSS、DOM、Web API 等几乎所有 Web 标准。WPT 的结果公开可查,形成了浏览器间的透明度和竞争压力。对于自研浏览器而言,从 Acid3 到 WPT 的过渡代表着从"基础能力验证"到"全面标准覆盖"的巨大跨越——目前主流浏览器在 WPT 上的通过率通常在 90-95% 之间,而新兴引擎可能仅达到 20-40%。
此外,浏览器还面临几方面严峻挑战:
- 安全性:沙箱隔离、漏洞防护等机制缺一不可
- 性能优化:JIT 编译、多进程架构等是流畅体验的基础
- 生态兼容:大量非标准但被广泛依赖的浏览器行为需要逐一适配
在性能方面,JIT(Just-In-Time)编译是现代 JavaScript 引擎的核心技术。与传统的逐行解释执行不同,JIT 编译器会在运行时识别"热点代码"(被反复执行的代码路径),将其编译为优化后的机器码。V8(Chrome)、SpiderMonkey(Firefox)和 JavaScriptCore(Safari)都采用多层 JIT 架构:先用解释器快速启动,再用基线编译器生成初步机器码,最后用优化编译器(如 V8 的 TurboFan)对热点代码进行激进优化(包括内联缓存、逃逸分析、类型特化等)。一个自研 JavaScript 引擎要达到主流引擎的性能水平,JIT 编译器的实现往往需要数年时间和大量工程投入。
在安全性方面,现代浏览器的安全架构基于"最小权限原则",通过多进程隔离和操作系统级沙箱来限制恶意网页的攻击面。以 Chrome 为例,每个渲染进程运行在受限的沙箱中,无法直接访问文件系统、网络或其他系统资源,所有敏感操作必须通过 IPC(进程间通信)请求浏览器主进程代为执行。这种架构确保即使渲染引擎存在漏洞被攻破,攻击者仍需突破沙箱边界才能危害用户系统。实现这一机制需要深入理解操作系统的安全原语(如 Linux 的 seccomp-bpf、Windows 的 Job Objects、macOS 的 App Sandbox),工程复杂度极高。
网络栈的深层复杂度
浏览器的网络栈同样是一个容易被低估的工程领域。它需要支持一系列复杂的协议和机制:HTTP/1.1 的持久连接和管线化、HTTP/2 的多路复用和头部压缩(HPACK)、HTTP/3 基于 QUIC 的 UDP 传输、TLS 1.3 加密握手、DNS 解析(包括 DNS-over-HTTPS)、Cookie 管理与同源策略、CORS 跨域资源共享、缓存控制(强缓存与协商缓存)、内容安全策略(CSP)等。每一层都有详尽的 RFC 规范和大量的安全考量。此外,现代浏览器还实现了连接优先级调度、预连接(preconnect)、预加载(preload)等性能优化策略,这些虽非标准兼容性测试的考察范围,但对实际使用体验影响巨大。
这些都是仅靠个人力量极难在短期内攻克的难题。
技术社区的反馈
从帖子目前的评论互动来看,Hacker News 社区对这类底层技术探索一贯抱有较高的敬意。这种项目往往能吸引到对浏览器引擎、编译器、系统编程感兴趣的核心技术人群,也有可能成为开源协作的起点。
造轮子精神依然珍贵
这条 Show HN 提醒我们,技术世界的"造轮子"精神从未消失。在 AI 工具与套壳产品泛滥的当下,愿意花两年时间啃下浏览器引擎这块硬骨头的独立开发者,本身就代表着一种值得尊敬的技术信念。
无论这款自研浏览器最终能否走向大众,它通过 Acid3 的这一刻,已经是一个值得记录的技术里程碑。对于任何想深入理解 Web 底层运作机制的开发者来说,这类项目也提供了难得的学习范本和灵感来源。
相关推荐

monolog:无需整理的AI笔记应用,语义搜索找回一切
monolog是一款取消文件夹和标签的AI笔记应用,用户只需像聊天一样记录想法,AI自动理解内容并通过语义搜索帮你找回信息。支持iOS、Android、Web等全平台同步。

AI编程助手为何这么烧钱?揭秘Harness背后的真实账单
深度解析AI编程助手Claude Code、Cursor、Cline等工具的隐形成本结构,揭示系统提示词、Agent往返震荡和Prompt缓存如何影响你的账单,提供实用的成本优化策略。

AirTag追踪揭秘:亚马逊疑似销毁珍本书训练AI
404 Media记者用AirTag追踪稀有书籍,发现其被送往亚马逊AI训练设施。调查揭示AI公司可能通过破坏性扫描珍本书获取训练数据,引发版权争议与文化遗产保护讨论。