无头浏览器不必从 Chrome 改:Lightpanda 用 Zig 从零造,100 个页面只占 123MB 内存

假设你要给一批 AI Agent 配浏览能力:五十个并发实例,每个实例都要打开真实网页、执行 JavaScript、填表单、读 DOM。用 headless Chrome 干这件事,内存账单会很难看,单实例轻松吃掉几百 MB,五十个实例就是几十 GB 起步,还没算 CPU 占用和每次冷启动的几秒钟。做爬虫和自动化的团队对这个痛点早就麻木了,麻木到很少有人回头问一句:为什么给机器用的浏览器,要背着一整套为人类肉眼准备的渲染引擎?Lightpanda 就是对这个问题的正面回答。它不 fork Chromium,不 patch WebKit,用 Zig 从零写了一个只为 AI Agent 和自动化存在的无头浏览器。GitHub 上四万一千多颗星,说明被这个问题折磨的团队不在少数。

一个不给人类渲染像素的浏览器

Lightpanda 的自我介绍只有一句话:专为 AI 和自动化设计的无头浏览器。这句话的关键不在无头,headless Chrome 也是无头;关键在专为 AI 设计。今天的网页离开 JavaScript 基本不转,Ajax、单页应用、无限滚动、即时搜索,React、Vue、Angular 这些框架把页面变成了一个需要真实执行脚本才能看到内容的程序。所以早早放弃渲染、只发 HTTP 请求的抓取方案在大多数现代站点上已经行不通,自动化工具必须有一个能跑 JavaScript 的内核。

问题是,现成方案只有 Chrome。Chrome 的设计目标是在屏幕上给人画出流畅、好看、带动画的页面,为此它带着完整的渲染管线、合成器、GPU 进程、字体排版、媒体解码。自动化场景里这些东西一个都用不上,但每一兆内存、每一个 CPU 周期你都得照付。有人可能会问,给 Chrome 加几个启动参数不就行了?答案是不行。Chrome 的无头模式关掉的只是窗口,渲染管线、合成器、GPU 进程照样在后台跑,内存大头一分不少。这不是开关问题,是架构问题。

Lightpanda 的判断很干脆:与其在 Chromium 里删减,不如从零造一个只保留自动化所需能力的浏览器。没有图形渲染引擎,没有给人看的任何一像素,内存全部交给 Zig 做显式管理。项目 2023 年 2 月开工,用 AGPL-3.0 许可证开源,截至我写作时仓库 41130 星、2021 个 fork,最近一次代码推送就在昨天。项目背后的团队同时维护着托管版云服务,开源版则是完整的自托管方案,两条线共用同一套内核。

123MB 对 2GB:官方基准的账

空口说轻量没有意义,Lightpanda 在 README 里放了一组可复现的基准:在 AWS EC2 m5.large 实例上,通过网络真实请求 933 个真实网页,取其中 100 页的数据做对比。

指标 Lightpanda Headless Chrome 差距
峰值内存(100 页) 123MB 2GB 约 16 倍
执行时间(100 页) 5 秒 46 秒 约 9 倍
图形渲染引擎 无 完整 Blink 架构差异
实现语言 Zig C++ 为主 ------
原生 Windows 版 无,走 WSL2 有 ------
许可证 AGPL-3.0 BSD 等宽松许可 ------

测试方法本身也值得交代。这不是挑几个静态页面跑出的宣传数字,而是官方 demo 仓库里公开的爬虫基准,通过网络真实请求 933 个站点,任何人都可以把那台 m5.large 开出来复跑一遍。m5.large 是 2 个 vCPU、8GB 内存的入门机型,选这个配置本身就说明测试目标是模拟成本敏感的生产环境,而不是堆硬件刷分。

先泼一盆冷水:这是官方自测数据,你的站点组合、网络条件和并发模型不同,数字一定会变。但这个差距的量级是结构性的,不是调参调出来的。一个不维护渲染树、不做布局合成、不碰 GPU 的浏览器,和一个背着完整图形栈的浏览器跑同样的抓取任务,内存差一个数量级是合理预期。再看一遍峰值内存那行:100 个页面同时打开只占 123MB,意味着单页常驻开销大约一两 MB,而 Chrome 侧是每页 20MB 上下。把它换算成成本语言:原来一台 64GB 的机器跑三十个 Chrome 实例就喘不过气,换 Lightpanda 之后同一台机器撑起几百个会话还有富余。对按实例计费的云端 Agent 平台,这不是优化,是定价模型的改写。

骨架是 Zig,心脏仍然是 V8

从零造浏览器听起来像是不自量力的玩具项目,Lightpanda 能跑通的关键在于它没有什么都自己造。JavaScript 引擎直接嵌 V8,和 Chrome 同款,所以 ES 新特性和各种奇技淫巧的站点脚本都能原样执行;HTTP 加载用 Libcurl;HTML 解析用 html5ever,这是 Servo 项目打磨多年的解析器。Zig 负责把这些成熟的 C 与 Rust 组件粘合成一个内存可控的整体,构建要求是 Zig 0.17.0。

为什么不 fork Chromium 改?因为 Chromium 是数千万行代码的庞然大物,fork 之后每天要跟着上游的安全补丁和架构演进跑,小团队根本追不动。Lightpanda 选择的组件策略是只借用经过时间验证的解析层和执行层,自己写调度和内存管理,这样上游升级时只需更换组件版本,不必合并整片森林。V8 还有一个细节:构建时可以把 V8 快照嵌进二进制,省掉每次启动生成快照的开销,冷启动更快,这对按任务拉起浏览器的场景很实在。

功能清单也能看出它对准的是自动化而不是浏览:CORS、DOM 树与 DOM API、XHR 和 Fetch、Cookie、自定义 HTTP 头、代理支持、网络拦截、内置广告拦截,外加一个遵守 robots.txt 的开关,启动时加上对应参数就会乖乖按站点规则抓。另一个值得注意的信号是测试态度:项目每天把 Web Platform Tests 的跑分结果公开发布在 perf.lightpanda.io 上,通过率和失败项一目了然。愿意每天晒自己考多少分的项目,通常比只在发布会 PPT 上晒分的项目可信。

CDP 照旧,现有脚本一行不改

换浏览器最大的隐性成本是改写自动化代码,Lightpanda 把这个成本压到了接近零。它原生实现 Chrome DevTools Protocol,也支持 WebDriver BiDi,Puppeteer 和 Playwright 脚本只需要把连接地址指过来。跑一个 CDP 服务只要一条命令:

bash 复制代码
docker run -d --name lightpanda -p 127.0.0.1:9222:9222 lightpanda/browser:latest
./lightpanda serve --obey-robots --host 127.0.0.1 --port 9222
./lightpanda fetch --dump markdown https://demo-browser.lightpanda.io/campfire-commerce/

Puppeteer 侧长这样,除了 connect 那一行,其余代码原样保留:

js 复制代码
import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const context = await browser.createBrowserContext();
const page = await context.newPage();
await page.goto('https://demo-browser.lightpanda.io/amiibo/', { waitUntil: 'networkidle0' });
const links = await page.evaluate(() =>
  Array.from(document.querySelectorAll('a')).map(a => a.getAttribute('href'))
);
console.log(links);
await browser.disconnect();

顺带一提,fetch 子命令本身就是个好用的瑞士军刀,可以把页面直接导出成 HTML、Markdown、PNG、PDF,或者用结构化数据模式把 JSON-LD、OpenGraph、Twitter Card 和 meta 标签打成一份 JSON,做内容清洗和 SEO 检查时不用再写一遍解析器。对付异步渲染的页面,fetch 提供了等待参数,可以等固定毫秒数、等某个选择器出现、或者等一段自定义脚本返回真值再导出,不需要为了等一个懒加载就把整个 Puppeteer 搬出来。PNG 导出要说明一下:它是文本级渲染的快照,适合快速确认页面结构,不是像素级保真截图,做视觉回归还是得靠真 Chrome。

还有两个面向生产环境的设计值得点名。CDP 服务除了监听 TCP 端口,还可以监听 Unix domain socket,文件权限直接设成仅属主可读写,同机多租户场景下比开端口安全。BiDi 协议支持则可以与 CDP 同时开启,意味着新标准的客户端和老生态的脚本可以共存在同一个实例上,迁移期不用二选一。Playwright 用户对应的入口是 connectOverCDP,同样只改连接参数那一行,页面对象、定位器、断言的写法全部原样保留,已有测试套件不需要跟着浏览器一起换。

Agent 模式与 PandaScript:LLM 打样,裸机复跑

浏览器自带 Agent 是今年新项目的标配,Lightpanda 的做法有一个少见的务实设计。它的 agent 子命令接受自然语言任务,控制浏览器导航、点击、填表、抽取结构化数据,模型提供方覆盖 Anthropic、OpenAI、Gemini、Vertex、Mistral、Hugging Face,以及 Vercel AI Gateway 和 OpenRouter 这类聚合网关,本地模型走 Ollama 或 llama.cpp,甚至可以登录 ChatGPT 订阅直接用 Codex,不必单独买 API key。还有一个工程细节:Agent 和浏览器跑在同一个进程里,每次工具调用都是进程内的直接操作,不像常见方案那样 Agent 进程通过 CDP 跟外部 Chrome 来回发消息,省掉了一整层 IPC 序列化开销,速度和内存优势在 Agent 模式下依然成立。

真正的巧思在输出端。一次 Agent 会话的产物是一份 PandaScript,本质是 vanilla JavaScript 加上一组内建在 Lightpanda 里的浏览器原语。会话里输入导出命令把脚本存下来,之后用 run 子命令离线重放,脚本执行是确定性的、零 token 消耗的。也就是说,开发阶段你让大模型反复试错把流程调通,生产环境跑的是一份不带任何模型的确定性脚本。LLM 负责探索,脚本负责执行,两个阶段的成本模型彻底分开。PandaScript 是普通 JavaScript 这件事也很关键:可以进 git、可以 code review、可以 diff,生产环境出问题时有据可查,而不是对着一堆模型采样记录猜当时发生了什么。只想手动操作的话还有不带模型的 REPL 模式,适合调试期逐条试命令。常用子命令也齐:带上任务参数可以一次性执行完就退出,适合脚本化调用;列出当前提供方可用模型的子命令则避免了猜模型名的尴尬。

MCP 服务的会话隔离做得比多数框架细

Lightpanda 内建 MCP 服务器,stdio 模式走标准 JSON-RPC 2.0,写进 MCP 配置就能被 Claude Code 这类客户端直接拉起。更值得关注的是 HTTP 模式:一条命令在 9223 端口起服务,多个 Agent 客户端同时往同一个端点 POST,互不干扰。隔离机制靠的是 Mcp-Session-Id 请求头:不带这个头发起 initialize 的客户端会被分到全新会话,响应里带回会话 ID,后续请求带上它就留在自己的会话里;两个 Agent 故意发同一个 ID 则共享同一份浏览上下文,适合多个 Agent 协同操作同一个页面的工作流。

会话还有显式管理接口,新建、列表、关闭都有对应工具,对某个会话发 DELETE 请求即可销毁。run 工具直接在调用方的会话里执行 PandaScript,默认 60 秒超时防止脚本卡死,脚本里打开的页面在结束时自动关闭,但 Cookie 和 storage 保留,登录态可以跨多次运行延续,这对需要先登录再干活的抓取流非常友好。脚本参数可以直接传源码字符串,也可以传之前保存的文件路径,返回值和控制台输出一起带回来。对后端工程师来说,接入形态就是一个 HTTP 端点,一条请求完成一次浏览任务,进程生命周期完全不用自己管。官方还单独维护了一个 Agent skill 仓库,给编码 Agent 装上就能直接调用。后端一条 curl 就能驱动浏览器:

bash 复制代码
lightpanda mcp --port 9223
curl -s http://127.0.0.1:9223/mcp -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"run","arguments":{"script":"const page = new Page(); await page.goto(\"https://example.com\"); return page.title();"}}}'

市面上不少 MCP 浏览器服务器是单页全局状态,两个 Agent 一并发就互相把对方的页面导航跑飞,Lightpanda 这个按会话隔页、隔 Cookie、隔内存的设计,直接命中了多 Agent 生产环境最疼的一点。

什么时候别换它

说了这么多优点,最后得把边界划清楚,否则就是误导。第一刀砍在许可证上:AGPL-3.0 是强 Copyleft,如果你要把 Lightpanda 嵌进闭源商业产品对外提供服务,法务这关必须先过,内部自用则基本无碍。第二刀是平台支持:没有原生 Windows 二进制,Windows 用户要么进 WSL2 要么用 Docker,团队里全是 Windows 机器的话接入成本要算进去。第三是兼容性上限:它每天公布的 WPT 成绩说明还有不少 Web 平台特性没覆盖,重度依赖复杂视觉渲染、WebGL、Canvas 指纹或媒体播放的站点,行为很可能和真实 Chrome 不一致,需要拿目标站点实测,不能假设能跑。

另外两个小坑:遥测默认开启,介意的话用环境变量关掉;nightly 二进制对 Linux 发行版的 glibc 版本有要求,x86_64 要 2.35 以上、arm64 要 2.38 以上,老镜像里直接跑会报加载器缺失。迁移之前建议做个小验证清单:拿五到十个目标站点的代表页面,用 fetch 加 Markdown 导出跑一遍,肉眼核对抽取结果是否完整,再抽样对比 Chrome 侧的结果,半天时间就能摸清兼容底线。我的建议是按场景切分:抓取、表单自动化、结构化数据抽取这类不需要视觉保真的任务,先切 Lightpanda,内存和速度的账面收益当天就能看见;需要像素级还原用户所见、跑回归截图对比的任务,继续留在 Chrome 系。浏览器这个三十年的老品类,第一次有项目公开承认它的用户不是人,这件事本身就值得四万个星标之外再多看一眼。

相关推荐
奈落243 小时前
AI辅助的另一面:从2026年国际AI安全报告的“故障”清单到国内专家的可靠性短板,自主行动的Agent为什么更难及时干预
人工智能·安全·agent·本地部署·ai 办公
火山引擎开发者社区5 小时前
eMudhra 证书失陷:容器用户最容易忽略的镜像信任链漏洞
人工智能
LabVIEW开发6 小时前
LabVIEW 机载 DIAL:每秒万次甲烷测量
人工智能·labview·labview知识·labview功能·labview程序
飞猫的边缘AI6 小时前
英特尔量子生意
人工智能·量子计算·边缘ai
深蓝AI6 小时前
桌面 Agent 缺的不是视觉:Vercel 开源 agent-desktop,用无障碍树 ref 替代截图坐标
人工智能·程序员
镜子AI7 小时前
镜子AI 技术复盘:三条自动化链路上的“停止条件“设计
运维·人工智能·自动化
向哆哆7 小时前
羊行为目标检测数据集:4类别、2,000张图像 | 目标检测
人工智能·yolo·目标检测·目标跟踪
如若1237 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
赛博守夜人8 小时前
AI安全攻防与治理之十六:对抗样本、恶意文件与多模态攻击,AI 内容安全检测的真实盲区
人工智能·安全