Lightpanda 深度解析:用 Zig 从零打造 AI 时代的无头浏览器——9 倍内存优化与 140 并发实例的架构内幕
引言:AI Agent 为什么需要一个全新的浏览器?
如果你做过 AI 自动化相关的项目,一定被 Chrome Headless 折磨过。一个实例 200-300MB 内存,启动要 3-4 秒,并发几十个实例服务器就嗷嗷叫。Playwright 和 Puppeteer 优化了 API 体验,但底层依然是 Chromium——给人类用的浏览器,强行塞给机器用,性能天花板就在那里。
Lightpanda 换了个思路:既然 AI Agent 不需要渲染像素,为什么要跑一个完整的浏览器引擎?
这个用 Zig 从零构建的无头浏览器,在 GitHub 上已经积累了 18k+ Star,官方基准测试显示:执行速度比 chromedp 快 9 倍,内存峰值降低 16 倍。更关键的是,它不是 Chromium 的精简版——这是一套全新的浏览器引擎,专为机器设计。
本文将深入剖析 Lightpanda 的架构设计、核心技术决策、实战部署方案,以及在 AI Agent 工作流中的最佳实践。
一、痛点分析:Chromium 的历史包袱
1.1 为什么 Chromium 不适合 AI 工作负载
Chromium 的架构是为人类浏览网页设计的,它要处理的事情包括:
- GPU 加速渲染与合成
- 多进程沙箱隔离
- 插件扩展系统
- DevTools 协议的完整实现
- 无障碍访问支持
- 各种 Web API 的兼容性处理
但在 AI Agent 场景下,你真正需要的只有:
- JavaScript 执行环境
- DOM 树的构建与查询
- 网络请求与响应处理
- 基本的 Cookie 和存储管理
其余 80% 的代码都是不必要的开销。这就像你只需要一把螺丝刀,却不得不随身带着整个工具箱。
1.2 实际的痛点数据
在一个典型的 AI 爬虫项目中,使用 Puppeteer + Chrome Headless 处理 1000 个页面:
| 指标 | Chrome Headless | 问题 |
|---|---|---|
| 单实例内存 | 200-300MB | 并发 50 个需要 10-15GB |
| 启动时间 | 2-4 秒 | 批量启动耗时显著 |
| 并发上限 | 约 20-30 个/核 | 多进程架构限制了扩展性 |
| 二进制大小 | 200MB+ | 容器镜像臃肿 |
| 崩溃恢复 | 需要外部监控 | 进程管理复杂 |
这些数字在 AI Agent 工作流中尤为致命——Agent 需要频繁打开页面、提取信息、关闭页面,每个操作都要等浏览器响应,延迟直接累积到 Agent 的执行时间中。
二、Lightpanda 架构深度解析
2.1 为什么选择 Zig
Lightpanda 选择 Zig 作为开发语言,这是一个非常关键的技术决策。Zig 的特性恰好匹配无头浏览器的需求:
编译时计算(Comptime):Zig 的 comptime 能力让很多在 C 中需要运行时处理的逻辑在编译期完成。在浏览器引擎中,大量的 DOM 属性映射、CSS 属性解析规则都可以在编译时生成查找表,避免运行时开销。
// 编译时生成 DOM 元素属性映射表
const ElementType = enum {
div, span, p, a, img, form, input, button,
// ...
};
fn getProperties(comptime etype: ElementType) type {
return switch (etype) {
.input => struct {
value: []const u8,
input_type: []const u8,
name: []const u8,
disabled: bool,
},
.img => struct {
src: []const u8,
alt: []const u8,
width: ?u32,
height: ?u32,
},
else => struct {
text_content: []const u8,
},
};
}
无隐式控制流:Zig 没有隐式异常处理、没有隐式内存分配,所有资源管理都是显式的。这对浏览器引擎至关重要——你清楚地知道每一块内存何时分配、何时释放,不会有垃圾回收器的停顿,也不会有异常处理栈展开的隐藏开销。
与 C 的无缝互操作:浏览器引擎不可避免地要集成一些 C 库(如网络协议栈、加密库)。Zig 可以直接 @cImport C 头文件,零成本调用 C 代码,不需要 FFI 绑定层。
const c = @cImport({
@cInclude("openssl/ssl.h");
@cInclude("openssl/err.h");
});
// 直接调用 OpenSSL,无绑定开销
pub fn initTls() !*c.SSL {
const ctx = c.SSL_CTX_new(c.TLS_client_method()) orelse return error.TlsInitFailed;
const ssl = c.SSL_new(ctx) orelse return error.TlsInitFailed;
return ssl;
}
2.2 核心架构:微内核 + 共享资源池
Lightpanda 的架构核心是一个微内核设计,将浏览器的功能拆分为可独立加载的模块:
┌─────────────────────────────────────────────┐
│ CDP Protocol Server │ ← 对外暴露 Chrome DevTools Protocol
├─────────────────────────────────────────────┤
│ Task Scheduler │ ← 任务调度,管理实例生命周期
├─────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Instance │ │ Instance │ │ Instance │ │ ← 轻量级浏览器实例(每个 20-30MB)
│ │ #1 │ │ #2 │ │ #140 │ │
│ └────┬─────┘ └────┬─────┘ └────┬──────┘ │
│ │ │ │ │
├───────┴─────────────┴─────────────┴───────────┤
│ Shared Resource Pool │ ← 共享只读资源
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐│
│ │ Font │ │ CSS │ │ JS │ │Network ││
│ │ Cache │ │ Parser │ │Compiler│ │ Stack ││
│ └────────┘ └────────┘ └────────┘ └────────┘│
├──────────────────────────────────────────────┤
│ Memory Allocator │ ← 自定义内存分配器
└──────────────────────────────────────────────┘
共享资源池是 9 倍内存优化的关键。在 Chrome 中,每个实例都有一份完整的字体缓存、CSS 解析器、JavaScript 编译器。Lightpanda 将这些只读资源提取到共享池中,新实例只需创建自己的 DOM 树和 JavaScript 执行上下文。
# 共享资源池概念示意
class SharedResourcePool:
"""所有浏览器实例共享的只读资源"""
def __init__(self):
# 这些资源只加载一次,所有实例共享
self.font_cache = FontCache.load_system_fonts() # ~5MB,一次加载
self.css_parser = SharedCSSParser() # CSS 规则解析引擎
self.js_compiler = SharedJSCompiler() # JS 字节码编译器
self.network_stack = SharedNetworkStack() # HTTP/2 连接池
class BrowserInstance:
"""轻量级浏览器实例"""
def __init__(self, shared_pool: SharedResourcePool):
# 引用共享资源(零拷贝)
self.fonts = shared_pool.font_cache
self.css_parser = shared_pool.css_parser
self.js_compiler = shared_pool.js_compiler
self.network = shared_pool.network_stack
# 实例专属资源(仅这部分是新分配的)
self.dom_tree = DOMTree() # ~2-5MB
self.js_context = JSContext() # ~3-8MB
self.cookies = CookieJar() # ~1MB
self.local_storage = Storage() # ~1MB
这种设计的效果:140 个实例共享 ~20MB 的基础资源,每个实例只需 ~20-30MB 的专属内存,总计约 3-4GB。同样的并发量在 Chrome Headless 下需要 28-42GB。
2.3 精简的渲染管线
Chrome 的渲染管线:HTML 解析 → DOM 构建 → CSSOM → 布局 → 绘制 → 合成 → GPU 光栅化。
Lightpanda 的渲染管线:HTML 解析 → DOM 构建 → CSSOM → 结束。
没有布局、没有绘制、没有合成、没有光栅化。AI Agent 需要的是 DOM 结构和 JavaScript 执行结果,不是像素。砍掉渲染管线后 60% 的代码量直接消失。
// Lightpanda 的 DOM 解析核心 - 简化的 HTML Tokenizer
pub const Tokenizer = struct {
buffer: []const u8,
pos: usize,
state: State,
pub const State = enum {
data,
tag_open,
tag_name,
attribute_name,
attribute_value,
// 没有 CSS 像素计算、没有布局状态
};
pub fn next(self: *Tokenizer) Token {
// 高效的状态机解析,只关心结构信息
switch (self.state) {
.data => {
// 快速跳过文本内容,只标记位置
const start = self.pos;
while (self.pos < self.buffer.len) : (self.pos += 1) {
if (self.buffer[self.pos] == '<') break;
}
return Token{ .text = self.buffer[start..self.pos] };
},
.tag_name => {
// 提取标签名,忽略视觉相关属性
const start = self.pos;
while (self.pos < self.buffer.len) : (self.pos += 1) {
const ch = self.buffer[self.pos];
if (ch == ' ' or ch == '>' or ch == '/') break;
}
return Token{ .tag_name = self.buffer[start..self.pos] };
},
else => unreachable,
}
}
};
2.4 JavaScript 执行引擎
Lightpanda 没有自己实现 JavaScript 引擎——这是明智的决定。它集成了系统已有的 JS 引擎(如 V8 或 QuickJS),但通过共享编译结果来优化:
class SharedJSCompiler:
"""跨实例共享 JS 编译结果"""
def __init__(self):
self._bytecode_cache = LRUCache(max_size=512) # 512 个编译后的脚本
async def compile_and_execute(self, source: str, context: JSContext):
# 检查是否已经编译过
cached = self._bytecode_cache.get(hash(source))
if cached:
# 直接执行缓存的字节码,跳过解析和编译
return await context.execute_bytecode(cached)
# 首次编译
bytecode = await self._engine.compile(source)
self._bytecode_cache.put(hash(source), bytecode)
return await context.execute_bytecode(bytecode)
这对 AI Agent 场景尤其有效:同一个 Agent 在不同页面上执行的 JavaScript 代码通常高度重复(提取标题、获取链接等),编译缓存命中率极高。
三、CDP 兼容:与 Puppeteer/Playwright 无缝对接
Lightpanda 暴露 Chrome DevTools Protocol (CDP) 接口,这意味着现有的 Puppeteer 和 Playwright 代码只需改一行连接方式就能迁移:
// 原来的 Puppeteer 代码
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
// 迁移到 Lightpanda - 只需改连接方式
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://localhost:9222'
// 其余代码完全不变!
});
// Lightpanda Cloud 版本
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://euwest.cloud.lightpanda.io/ws?token=YOUR_TOKEN'
});
但需要注意 CDP 兼容性不是 100% 完整的。Lightpanda 专注于 AI 自动化所需的核心能力:
完全支持:
Page.navigate— 页面导航Runtime.evaluate— JavaScript 执行DOM.querySelector/DOM.querySelectorAll— DOM 查询Network域 — 网络请求拦截与监控Page.getContent— 获取页面内容Runtime.getProperties— 获取 JS 对象属性
部分支持:
Emulation域 — 设备模拟(仅 User-Agent)Security域 — 证书信息(基础支持)
不支持:
CSS.getComputedStyle— 不需要视觉样式Page.screenshot— 没有像素渲染Overlay域 — 没有视觉高亮Performance域的渲染指标 — 没有渲染管线
四、实战:构建 AI Agent 的 Web 自动化工作流
4.1 基础部署
# Docker 部署(推荐)
docker pull lightpanda/browser:latest
docker run -d \
--name lightpanda \
-p 9222:9222 \
--memory=4g \
--cpus=2 \
lightpanda/browser:latest
# 健康检查
curl -s http://localhost:9222/json/version | jq .
4.2 AI Agent 网页信息提取
import asyncio
from playwright.async_api import async_playwright
class LightpandaWebAgent:
"""基于 Lightpanda 的 AI Agent 网页交互工具"""
def __init__(self, ws_endpoint='ws://localhost:9222', max_concurrent=50):
self.ws_endpoint = ws_endpoint
self.max_concurrent = max_concurrent
self._semaphore = asyncio.Semaphore(max_concurrent)
async def extract_page_info(self, url: str) -> dict:
"""提取页面结构化信息供 LLM 分析"""
async with self._semaphore:
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(self.ws_endpoint)
page = await browser.new_page()
try:
await page.goto(url, wait_until='domcontentloaded', timeout=15000)
# 提取结构化内容 - 这是给 LLM 用的精简数据
data = await page.evaluate('''() => {
const getCleanText = (el) => {
return el.innerText?.trim().replace(/\\s+/g, ' ') || '';
};
// 提取页面核心结构
const result = {
url: location.href,
title: document.title,
meta: Object.fromEntries(
[...document.querySelectorAll('meta')]
.filter(m => m.name || m.property)
.map(m => [m.name || m.property, m.content])
),
headings: [...document.querySelectorAll('h1,h2,h3')]
.map(h => ({ level: h.tagName, text: getCleanText(h) }))
.slice(0, 20),
links: [...document.querySelectorAll('a[href]')]
.map(a => ({ text: getCleanText(a), href: a.href }))
.filter(l => l.text && !l.href.startsWith('javascript:'))
.slice(0, 50),
mainContent: getCleanText(
document.querySelector('main, article, [role="main"]') || document.body
).slice(0, 5000),
forms: [...document.querySelectorAll('form')]
.map(f => ({
action: f.action,
method: f.method,
inputs: [...f.querySelectorAll('input,select,textarea')]
.map(i => ({ name: i.name, type: i.type }))
}))
};
return result;
}''')
return data
finally:
await page.close()
await browser.close()
async def batch_extract(self, urls: list[str]) -> list[dict]:
"""批量提取多个页面的信息"""
tasks = [self.extract_page_info(url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
return [
{'url': url, 'data': r, 'error': None}
if not isinstance(r, Exception)
else {'url': url, 'data': None, 'error': str(r)}
for url, r in zip(urls, results)
]
# 使用示例
async def main():
agent = LightpandaWebAgent(max_concurrent=100)
urls = [
'https://news.ycombinator.com',
'https://github.com/trending',
'https://lobste.rs',
] * 20 # 60 个 URL
results = await agent.batch_extract(urls)
success = sum(1 for r in results if r['error'] is None)
print(f"成功: {success}/{len(results)}")
# 将提取结果喂给 LLM 进行分析
for r in results:
if r['data']:
print(f"[{r['data']['title']}] {r['url']}")
asyncio.run(main())
4.3 AI Agent 的智能表单填写
async def smart_form_fill(agent: LightpandaWebAgent, url: str, form_data: dict) -> bool:
"""AI Agent 智能填写表单"""
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(agent.ws_endpoint)
page = await browser.new_page()
try:
await page.goto(url, wait_until='domcontentloaded')
# 分析表单结构
form_info = await page.evaluate('''() => {
const form = document.querySelector('form');
if (!form) return null;
return {
action: form.action,
method: form.method,
fields: [...form.querySelectorAll('input,select,textarea')].map(el => ({
name: el.name,
type: el.type,
id: el.id,
label: el.labels?.[0]?.textContent?.trim() ||
el.getAttribute('aria-label') ||
el.placeholder || '',
required: el.required,
options: el.tagName === 'SELECT' ?
[...el.options].map(o => ({ value: o.value, text: o.text })) :
undefined
}))
};
}''')
if not form_info:
return False
# 根据字段名称和标签智能匹配数据
for field in form_info['fields']:
value = None
# 尝试多种匹配策略
for key, val in form_data.items():
key_lower = key.lower()
name_lower = (field['name'] or '').lower()
label_lower = field['label'].lower()
if key_lower in name_lower or key_lower in label_lower:
value = val
break
if value is None:
continue
# 填写字段
selector = f'[name="{field["name"]}"]' if field['name'] else f'#{field["id"]}'
if field['type'] in ('text', 'email', 'password', 'search', 'tel', 'url'):
await page.fill(selector, str(value))
elif field['type'] == 'select-one' and field['options']:
# 选择最匹配的选项
best_match = max(
field['options'],
key=lambda o: len(set(str(value).lower()) & set(o['text'].lower()))
)
await page.select_option(selector, best_match['value'])
elif field['type'] == 'checkbox':
await page.set_checked(selector, bool(value))
# 提交表单
submit_btn = await page.query_selector('button[type="submit"], input[type="submit"]')
if submit_btn:
await submit_btn.click()
return True
finally:
await page.close()
await browser.close()
4.4 性能基准测试
import time
import statistics
import asyncio
from playwright.async_api import async_playwright
async def benchmark_comparison(url: str, iterations: int = 20):
"""对比 Lightpanda 与 Chrome Headless 的性能"""
results = {'lightpanda': [], 'chrome': []}
# Lightpanda 测试
for _ in range(iterations):
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp('ws://localhost:9222')
page = await browser.new_page()
start = time.monotonic()
await page.goto(url, wait_until='domcontentloaded')
content = await page.content()
elapsed = time.monotonic() - start
results['lightpanda'].append({
'time': elapsed,
'content_size': len(content)
})
await page.close()
await browser.close()
# Chrome Headless 测试
for _ in range(iterations):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
start = time.monotonic()
await page.goto(url, wait_until='domcontentloaded')
content = await page.content()
elapsed = time.monotonic() - start
results['chrome'].append({
'time': elapsed,
'content_size': len(content)
})
await page.close()
await browser.close()
# 输出对比
for engine in ['lightpanda', 'chrome']:
times = [r['time'] for r in results[engine]]
print(f"\n{engine.upper()}:")
print(f" 平均: {statistics.mean(times):.3f}s")
print(f" 中位: {statistics.median(times):.3f}s")
print(f" P95: {sorted(times)[int(len(times)*0.95)]:.3f}s")
print(f" 标准差: {statistics.stdev(times):.3f}s")
lp_avg = statistics.mean([r['time'] for r in results['lightpanda']])
ch_avg = statistics.mean([r['time'] for r in results['chrome']])
print(f"\n⚡ Lightpanda 比 Chrome 快 {ch_avg/lp_avg:.1f}x")
asyncio.run(benchmark_comparison('https://news.ycombinator.com'))
五、与 Obscura 等 Rust 无头浏览器的对比
有人会问:同样是为 AI 设计的无头浏览器,Lightpanda(Zig)和 Obscura(Rust)有什么区别?
| 维度 | Lightpanda (Zig) | Obscura (Rust) |
|---|---|---|
| 二进制大小 | ~30MB | ~30MB |
| 目标场景 | Web 自动化 + AI Agent | AI Agent 专用(更极致) |
| CDP 兼容 | 完整 CDP,支持 Puppeteer/Playwright | 自有 API |
| JavaScript 引擎 | 集成 V8/QuickJS | 集成 QuickJS |
| 社区生态 | 较大(18k+ Star) | 较小 |
| Cloud 服务 | 有(lightpanda.io) | 无 |
| 渲染管线 | HTML → DOM → CSSOM | HTML → DOM(更精简) |
| 语言选择理由 | comptime、显式内存管理、C 互操作 | 生态成熟、安全保证 |
选择建议:
- 需要兼容现有 Puppeteer/Playwright 代码 → Lightpanda
- 需要极致的小体积和简单性 → Obscura
- 需要云服务托管 → Lightpanda Cloud
- 纯 AI Agent 场景不需要完整 CDP → 两者皆可,Obscura 更轻
六、生产环境部署最佳实践
6.1 容器化部署与资源限制
# docker-compose.yml
version: '3.8'
services:
lightpanda:
image: lightpanda/browser:latest
ports:
- "9222:9222"
deploy:
resources:
limits:
memory: 4G
cpus: '2'
reservations:
memory: 1G
cpus: '0.5'
environment:
- LIGHTPANDA_MAX_INSTANCES=140
- LIGHTPANDA_INSTANCE_TTL=300 # 实例最大存活 5 分钟
- LIGHTPANDA_SHARED_POOL_SIZE=64 # 共享资源池 64MB
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9222/json/version"]
interval: 10s
timeout: 5s
retries: 3
# 可选:Nginx 反向代理做负载均衡
lightpanda-lb:
image: nginx:alpine
ports:
- "9223:9223"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- lightpanda
6.2 多实例负载均衡
# nginx.conf - Lightpanda 负载均衡
upstream lightpanda_pool {
least_conn; # 最少连接优先
server lightpanda-1:9222;
server lightpanda-2:9222;
server lightpanda-3:9222;
keepalive 64;
}
server {
listen 9223;
location / {
proxy_pass http://lightpanda_pool;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
}
}
6.3 监控与告警
import asyncio
import aiohttp
from dataclasses import dataclass
@dataclass
class LightpandaMetrics:
active_instances: int
memory_usage_mb: float
request_rate: float
error_rate: float
async def monitor_lightpanda(endpoint: str = 'http://localhost:9222'):
"""定期采集 Lightpanda 的运行指标"""
async with aiohttp.ClientSession() as session:
while True:
try:
# 获取活跃页面列表
async with session.get(f'{endpoint}/json/list') as resp:
pages = await resp.json()
active = len(pages)
# 获取版本信息(含内存等状态)
async with session.get(f'{endpoint}/json/version') as resp:
version = await resp.json()
metrics = LightpandaMetrics(
active_instances=active,
memory_usage_mb=0, # 需要从容器监控获取
request_rate=0,
error_rate=0,
)
# 告警逻辑
if metrics.active_instances > 120:
print(f"⚠️ 活跃实例数 {metrics.active_instances} 接近上限 140")
if metrics.active_instances == 0:
print("⚠️ 没有活跃实例,服务可能异常")
except Exception as e:
print(f"❌ 监控采集失败: {e}")
await asyncio.sleep(30)
七、AI Agent 框架集成
7.1 与 LangChain 集成
from langchain.tools import tool
from playwright.async_api import async_playwright
@tool
async def browse_webpage(url: str) -> str:
"""使用 Lightpanda 浏览网页并提取内容。输入 URL,返回页面文本内容。"""
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp('ws://lightpanda:9222')
page = await browser.new_page()
try:
await page.goto(url, wait_until='domcontentloaded', timeout=15000)
content = await page.evaluate('''() => {
const main = document.querySelector('main, article, [role="main"]');
const el = main || document.body;
return el.innerText.slice(0, 8000);
}''')
return content or "无法提取页面内容"
finally:
await page.close()
await browser.close()
# 在 Agent 中使用
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
tools = [browse_webpage]
llm = ChatOpenAI(model="gpt-4o")
# ... 创建并运行 Agent
7.2 与 OpenClaw 集成
Lightpanda 已经被集成到多个 AI Agent 框架中,包括 OpenClaw 的 xbrowser skill、hermes-agent、trigger.dev 等。通过 CDP 协议的标准化接口,任何支持 Puppeteer/Playwright 的框架都可以零成本迁移。
八、局限性与未来展望
8.1 当前局限
- CDP 兼容性不完整:不支持截图、PDF 导出等视觉功能,如果你的 Agent 需要视觉理解,仍然需要 Chrome Headless
- Web API 覆盖有限:一些高级 Web API(WebGL、WebRTC、Service Worker)尚未支持
- JavaScript 兼容性:某些复杂的 SPA 应用可能无法正确渲染,特别是依赖特定 Chrome 特性的网站
- 社区生态早期:虽然 Star 数增长快,但生产级部署案例还不多
8.2 未来方向
- WASM 模块化:计划将核心引擎编译为 WASM,实现浏览器内运行浏览器的递归场景
- 结构化输出:直接输出 JSON/XML 结构而非原始 HTML,减少 LLM 的 token 消耗
- 内置 AI 预处理:在浏览器层面完成文本清洗、去噪,减少后续处理负担
- 分布式实例调度:支持跨节点的实例池管理
九、总结
Lightpanda 不是一个"更好的 Chrome Headless"——它是一个全新的物种。它回答了一个根本问题:如果浏览器不是给人用的,那它应该长什么样?
答案是:30MB 二进制、20MB 内存、0.5 秒启动、140 并发实例、9 倍速度提升。
对于 AI Agent 开发者来说,Lightpanda 提供了三个核心价值:
- 成本降低:同样并发量下内存消耗降低 10 倍,直接降低云服务器成本
- 速度提升:Agent 的每个网页操作都快 3-9 倍,整个工作流的延迟显著降低
- 架构简化:不需要管理复杂的 Chrome 进程池,Docker 一个容器搞定
如果你在做 AI Agent、网页爬虫、自动化测试,Lightpanda 值得一试。迁移成本极低——改一行连接代码,其他不变。最坏的情况,你切回 Chrome 就行,没有任何风险。
项目地址:https://github.com/lightpanda-io/browser
官网:https://lightpanda.io