读时间戳,别读落地页
我有个习惯:几个大的 headless 浏览器一发版,我就去翻它们的 issue 区。不是去看热闹——一个项目自己给自己开的工程票,是全网最诚实的浏览器规范进度表。star 数量衡量的关注度,落地页衡量的是文案水平,而某处规范角落到底是哪天关掉的,衡量的才是工程。这个没法吹。
今天有个 35k star 的 Zig 写的 headless 浏览器发了 0.4.1。我对着它的 release notes 翻我们自己的 git log,发现一件事:这周它们开票的、刚发版的几个东西,我们几天前就已经 ship 了。下面不放形容词,只有时间戳和链接,每条都可以自己去点开验。
对账单
| 能力 | 他们 | 我们 | 差距 |
|---|---|---|---|
click 派发完整 pointer/mouse 事件序列,不是孤零零一个 click |
0.4.1 发版,9 月 15 日 | ab2baa7,9 月 6 日 | 早 9 天 |
| 重定向把 POST 改写成 GET 时,body 和描述它的那堆头必须跟着丢(fetch 重定向语义) | #3526,9 月 15 日开票,还开着 | 3d5f0bc + 48fa1ec,9 月 11 日 | 早 4 天;一边开着一边已落地 |
<body> 上写了 overflow,到底哪个盒子在滚——css-overflow-3 §3.3 向视口传播 |
#3523,9 月 15 日开票,还开着 | 4f26dec,9 月 14 日 | 早 1 天;一边开着一边已落地 |
| CSS 自定义属性 | 0.4.1 里是 "basic support",9 月 15 日 | 208518a,9 月 4 日——var() 替换 + CSSOM 读回 |
早 11 天 |
Fetch Referrer Policy——文档头、<meta>、逐请求覆盖 |
#3485,9 月 10 日开票,还开着 | cb0c34e + 42deef0,9 月 14–15 日 | 他们先开的票,我们先落地 |
| 建 context 时带 storage state | #1550,2 月 14 日开的,到现在 | v0.2.7,9 月 4 日——session 导出/恢复,含 localStorage | 开了 7 个月 |
第五行要单独说:Referrer Policy 那条,他们开票比我们落地早四天。照样放进来,因为对账单要是经不起看,就不是对账单了。而且这个比法本来就不是「谁先开票」——是「谁先 ship」。六条里五条,我们这边已经落地,他们那边还开着(或刚发)。
为什么老是撞车
两个团队都在啃同一套规范,撞到的角落自然是同一批——fetch 重定向语义、overflow 传播、pointer 事件,规范摆在那,顺序也差不多。这恰恰是时间戳公平的原因:谁也没抄谁,规范是公开的,你哪天关掉这个角落也是公开的。
该给的分也要给,而且口径要说准:他们 0.4.1 上了实验性的完整 CORS(--experimental-features cors),我们这块做的是 preflight 强制执行。论广度他们领先。这种良性你追我赶,对在上面盖 agent 的所有人都是好事。
不算比赛的三件事
有三条线,两边根本不在同一个轴上比:
- 像素。他们明确一个像素都不渲染("no rendering overhead",
--dump png输出的是文本)。我们这边真出图:截图、PDF、视频都从我们维护的 Rust 布局绘制栈里来,整页 532 毫秒、227 MB——同一页 Chrome 要 4053 毫秒、2.1 GB。 - 指纹。他们的网络栈是 libcurl,指纹就是 libcurl。我们 TLS 层仿的是 Chrome 145——因为生产环境里半个互联网对「JA3 不对」的回答就是一堵墙。
- 许可证。AGPL-3.0 对 Apache-2.0。法务部门有意见的公司,这一条在 demo 之前就分出胜负了。
随便抄
这篇是方法论,不是踩人。你要选 agent 浏览器,别读落地页——把你家 agent 真正会碰到的五处 web 平台角落列出来,去查日期。我们的日期全部公开,上面每个链接都点得开。
这篇是快照。活版本的记分牌——同一套方法,扩到整个 agent browser 赛道(browser-use、Kitesurf 都在),每轮发版重新对一次账——住在仓库里:docs/RECEIPTS.md。
而且是 Apache-2.0。你要自己做浏览器,上面哪个 commit 能帮你省一周,拿去。