给 AI Agent 打造专用浏览器:性能提升 7.6 倍、内存降至十分之一的架构实践
给 AI Agent 写了个浏览器实测比 Chrome 快 7.6 倍、内存只有十分之一先交代一下背景。我一直在做 AI Agent 方向的基础设施主要帮团队把各种 Agent 工作流从能跑推到能低成本稳定跑。做到后面发现瓶颈不太在模型本身反而卡在了一个几乎没人认真对待的环节Agent 在浏览器里执行任务时开销太离谱了。一个正常的页面自动化流程Chrome 开三五个 tab、跑十几分钟内存轻轻松松十几个 GB。更难受的是稳定性——标签页动不动就崩长任务跑到一半白屏重来一次的成本比模型 API 还贵。所以我干了一件事给 AI Agent 专门写了一个浏览器内核砍掉所有人类浏览习惯需要的功能只保留 Agent 执行任务所需的通路。实测下来端到端任务完成时间平均比 Chrome 快 7.6 倍内存占用大概只有 Chrome 的十分之一。今天不聊概念把整个项目的设计思路、实现细节、以及测试中那些不容易从文档里找到的经验一次说清楚。1. 为什么通用浏览器跑不动 Agent 任务Chrome 的架构和 Agent 的工作负载天生冲突先说一个反直觉的结论Chrome 慢不是因为它不优秀而是因为它太优秀了——它得为人类上网这个超宽泛的场景做到面面俱到。而 AI Agent 在浏览器里干的事情本质上和人类上网是两种完全不同的计算模式。1.1 人类浏览 vs Agent 执行两种根本不同的工作模式人类浏览网页时行为模式是打开页面、眼睛扫视、滚动、点击、思考、再点击。这个过程中渲染引擎只需要优先保证用户当前看到的这一块区域尽可能快地呈现其他部分可以慢慢懒加载。Chrome 的整套优化——比如视口优先渲染、用户交互中断优先、延迟加载不可见资源——都是围绕人的注意力设计的。AI Agent 在浏览器里执行任务时是另一套逻辑读取 DOM、解析结构、定位元素、发起 XHR、等待异步响应、提取数据、填表、点击、翻页。它不需要看到页面它需要读透页面。它不会对某个像素产生兴趣它只关心 DOM 树、iframe、网络响应和状态变化。这意味着什么Chrome 把大量 CPU 周期花在了 Agent 根本不需要的事情上合成器计算、图层管理、光栅化、GPU 贴图。Agent 真正需要的是从 URL 到最终可操作 DOM 的那条最短路径Chrome 却背着渲染、动画、布局恢复、后台标签节流这些大包袱跑。相当于你明明只需要送一份文件却开了辆满载货物的大型卡车。1.2 多进程架构的隐性成本Agent 场景下的性能账单Chrome 的多进程架构有个著名的口号一个 tab 崩了不影响其他 tab。这个设计对人类用户非常友好但对 Agent 来说是纯纯的负资产。每个 tab 一套独立的渲染进程、GPU 进程、网络进程的通信管道内存开销摆在那里。实测数据一个空白的新 tab 在 Chrome 里大概占 40-60 MB打开一个中等复杂度的企业后台页面常驻内存轻松到 500 MB 以上。而 Agent 跑任务时候的状态是多个 tab 并行、长轮询连接挂着、SPA 应用不断更新 DOM。我之前用 Chrome DevTools Protocol 做了一套比较完整的 Agent 操作框架跑一个中等规模的数据采集任务8 个 tab 并发峰值内存 30 GB 是常有的事。这个消耗不仅是成本问题还有稳定性——Chrome 只要检测到内存压力大立刻开始回收后台 tab而 Agent 根本不知道自己的页面已经被冻结了只能等到超时然后报错。1.3 Chrome 不是不好而是它服务错了对象我并不是想否定 Chrome。我非常尊敬 Chromium 团队的工程能力V8 引擎优化得极其出色。但本质上Chrome 的设计哲学是人类用户优先它的每项优化都以人怎么看、怎么点、怎么感知为基准。而 AI Agent 是另一个物种它的注意力模型完全不同所以给它用的浏览器不能只是 Chome 加个插件而要把浏览器底层的资源调度策略、渲染策略、进程模型全部推翻重来。这也是这个项目的出发点不优化 Chrome而是写一个为 Agent 的工作负载从头设计的浏览器。不追求Chrome 的体验更快一点而是追求Agent 场景下系统级的最小开销和最大吞吐。2. 核心设计取舍砍掉视觉渲染重构资源调度给 Agent 用的浏览器最应该明确的一个设计原则是Agent 不看页面Agent 读页面。所以传统浏览器的渲染管线——布局、绘制、合成、显示——在 Agent 场景下几乎全部可以砍掉或者极度简化。我并不是第一个想到这个方向的但可参考的开源实现太少很多方案还停留在一个简单的 HTTP 客户端加正则解析的层面那个碰到现代前端框架就废了。我需要的是一个能执行 JavaScript、能跑 React/Vue 应用、能和复杂页面完整交互的真正的浏览器内核但去掉传统浏览器的视觉输出。2.1 选型与架构从 Chromium 剥离还是从零自研在项目启动前我认真评估过两条技术路线方案优点缺点适用场景基于 Chromium 内核裁剪如 CEF、Electron 底子改造兼容性好JS 执行、DOM 解析全部现成底层耦合太深内存和性能优化空间有限很多坑藏在深处短期快速出成果、兼容性优先自研轻量渲染内核 现有 JS 引擎V8/QuickJS按需设计性能优势明显极致可控工作量大常见页面兼容性需要自己维护中长期投入、追求极致性能与可控性我最终选择的是第三条路混合架构。核心思路是分离 JS 执行与 DOM 构建。利用 V8 作为 JavaScript 执行引擎但 DOM 的构建和操作完全自己写。这样既拿到了 V8 极致的 JS 执行性能又完全不背 Compositor、Renderer、GPU 那口大锅。付出的代价是我需要自己实现一套 DOM 绑定和事件循环去适配 V8 的 API 语义。这个工作量比预想的大但换来的是从底层到顶层完全按自家需求裁剪的自由度。架构上分了四层网络层复用系统 HTTP/2 客户端加自研连接池和智能请求合并。解析与执行层HTML 解析器、CSS 解析器只解析会影响 DOM 主树的规则、JavaScript 执行环境V8。DOM 与交互层完整实现 DOM API、事件循环、Fetch/XHR这套是 Agent 感知页面世界的全部通道。协议控制层面向 Agent 的上层接口把页面状态、可操作元素、异步事件抽象成 JSON 流Agent 可以通过这套协议完成看、点、填、等等操作。2.2 渲染管线的反设计跳过那些 Agent 永远不需要的步骤如果说这条架构路线有一个灵魂那就是渲染管线的反向设计。传统浏览器里这条管线是HTML → DOM → CSSOM → Render Tree → Layout → Paint → Composite → Display。Agent 场景下我把这条管线改成了HTML → DOM →Agent-Ready Tree→ 协议输出。Layout、Paint、Composite、Display这四步全部不需要执行直接删掉。对应节省的时间非常可观——一个中等复杂度的生产环境页面首次渲染时 Layout Paint 的时间通常占总耗时的 60%-70%。与此同时CSS 不需要被完整解析只解析影响 DOM 可见性和交互性的一部分比如 display、visibility、pointer-events其余 CSS 规则全部跳过。DOM 虽然要完整构建但它不需要绑定任何像素坐标和图层关系内存占用直接从节点级降到纯树级。这一步完成后单页面的可操作时间从平均 870msChrome 实测降到 113ms提升了大约 7.7 倍。所有 Agent 高频操作——元素定位、属性读取、表单填充、状态轮询——都建立在这棵 Agent-Ready Tree 上。它比 DOM 树更精简因为只保留 Agent 需要关注的节点类型和属性又比纯 JSON 视图更完整因为它能动态响应 JavaScript 引起的 DOM 变化。2.3 资源调度重构让每个页面只保留真正运行需要的资源砍掉渲染管线之后内存的大头就剩两块JavaScript 堆和 DOM 树。Chrome 的多进程架构在这块资源调度的账是这么算的每个 tab 是独立进程分配独立的 JS 堆和渲染资源相互隔离换取稳定性。Agent 场景不需要这种隔离我采用了一个共享宿主 弱隔离上下文的模型——多个 Agent 页面共享同一个进程池但每个页面在逻辑上使用独立的 V8 Context堆内存按需动态分配闲置页面可以立刻整页回收而不是靠 Chrome 那套后台 tab 冻结的逻辑延迟处理。一个直接的收益是并发能力的提升。Chrome 在 32GB 内存的机器上跑我那个数据采集任务并发 tab 数在 6 个左右就开始触发内存预警。这个项目在同一台机器上并发 tab 数跑到 27 个内存才有压力。而且每个 tab 的内存基线从 Chrome 的几百 MB 降到了几十 MB。3. 性能数据的完整测算7.6 倍和十分之一是怎么得出来的数据没有测试方法就没有意义。7.6 倍和十分之一这两个数我不希望它只是标题党式的我给 Chrome 泼脏水而是建立在可复现测试环境和对比基准上的实测结果。3.1 测试环境与对比方法测试机器统一用同配置的裸机Intel i7-12700K64GB DDR5NVMe SSDUbuntu 22.04 LTS。Chrome 版本是 116 稳定版外挂 Chrome DevTools Protocol 驱动本项目浏览器使用相同的 CDP 风格协议驱动保证上层操作一致。测试任务分了三类覆盖 Agent 高频行为SPA 长任务型打开一个企业级 React 后台模拟真实仪表盘等待首屏可用然后持续执行数据刷新操作 10 分钟。并发页面采集型同时打开 8 个不同域名的新闻类页面等待所有页面完成了可见内容加载逐个提取正文文本与图片链接。复杂交互流程型完成一个跨系统购买流程——打开商品列表页、翻页、筛选、打开详情、加入购物车、进入结算页、填写表单、提交。全程含多级跳转和异步等待。为什么选这三类因为它们恰好覆盖了 Agent 工作的三大耗时模式单页长时间运行对应监控/数据分析 Agent、多页并发信息采集对应爬取/聚合类 Agent、流程完整通过对应自动化操作类 Agent。基准线都用任务完成时间来测而不是用 Lighthouse 那种页面加载性能评分。任务类型Chrome 平均耗时本项目平均耗时加速比SPA 长任务稳定态46.8s含 3 次白屏中断6.2s7.5x并发页面采集8 tab52.4s7.1s7.4x复杂交互流程87.5s11.4s7.7x3.2 内存占用的实测口径内存这部分我用的是 RSSResident Set Size口径就是操作系统实际分配给该进程组的物理内存量。逐个 tab 的详细数如下场景Chrome 平均 RSS / tab本项目平均 RSS / tab对比空白页48.2 MB6.8 MB14%新闻门户426 MB51.3 MB12%React 管理后台638 MB72.6 MB11.4%视频站不播放387 MB46.1 MB11.9%综合来看常规页面的内存占用大约是 Chrome 的 10%-14%和十分之一这个说法基本吻合。长任务高压力场景下差距更大同一套 8 tab 并发采集任务Chrome 峰值 RSS 到了 29.7 GB本项目是 4.8 GB这个达到了六分之一。这里的核心原因有两层第一砍掉渲染管线之后每个页面的内存开销大幅减少这是表层的第二更关键的是资源复用——多个页面共享同一个 DOM 解析器、CSS 解析器和网络连接池而 Chrome 每 tab 都是独立进程同样的基础代码每个进程都要加载一份内存本来就是重复消耗。3.3 这个 7.6 倍到底意味着什么我听到过一种质疑这项目是不是没渲染所以快是不是作弊我觉得不是。Agent 使用浏览器时它的输出目标本来就不是像素而是数据与结构。传统浏览器的渲染发生在 GPU 光栅化和合成器里Agent 场景根本不消费这个输出那这部分计算对 Agent 而言就是纯浪费。这个 7.6 倍不是牺牲功能换速度而是抹掉无用功之后的自然结果。换个角度验证如果让 Agent 输出一个页面的外观看板那这个浏览器毫无优势但凡是让 Agent 执行语义级操作——抓数据、填表单、跑流程——它显然应该用为语义操作调优的工具而不是为人类视觉准备的渲染器。当然也要说明这组测试是我在自己团队的真实业务场景上跑的不代表所有页面和所有 Agent 框架都会有 7 倍以上的提升。如果你的 Agent 主要跑的是静态文档、纯文本页面这个收益会小很多因为那些页面在 Chrome 里本身开销就不大。如果你的 Agent 有大量重前端框架交互比如 React 状态频繁更新导致 DOM 大范围变换那这个架构的收益反而更大——Chrome 会为这些变化触发大量重排重绘我的实现里根本没有重绘这个开销。4. 深度优化策略从 DOM 构建到 JS 调度的层层压榨架构确立之后真正的工程难点在微观层面。能跑到 7 倍以上靠的不只是砍渲染这一个宏观决策而是几十处微观优化的合力。这节挑几个对结果贡献最大的点每个都写清楚原理方便大家复用思路。4.1 DOM 构建阶段跳过 CSS 计算的链路压缩传统 HTML 解析器在构建 DOM 的过程中会同步做 CSS 解析和样式计算至少是增量式的因为后续渲染管线需要这些信息。我的实现里CSS 解析被推迟到 DOM 构建完成之后按需执行而且只响应 Agent 真正会查询的样式属性。这时候有一个关键点要处理JavaScript 代码可能在 DOM 构建过程中执行getComputedStyle这种操作是否需要拦截、转为延迟我的做法是getComputedStyle只返回一份简化的样式对象——只含盒模型的几个核心值其他属性统一返回默认值。对于 Agent 场景这套简化返回在绝大多数情况下足够用。九成以上的前端框架和脚本不会因为缺少text-shadow的具体值而报错至于极少数拿getComputedStyle做特性检测的页面我专门准备了一个兜底表用常见浏览器的默认行为填充。这样改完单页面的 DOM 可用时间普遍缩短了 80-120ms看起来不多但乘上 Agent 动辄几十上百次页面跳转累计节省非常可观。4.2 JavaScript 执行效率V8 的上下文复用与编译缓存机制JavaScript 是现代网页的灵魂也是 Agent 场景下唯一绕不开的硬成本。在这个项目里JS 执行的比重比传统浏览器更大因为没有渲染所有动态行为都归结为 JS 的执行结果。V8 本身已经非常快但我还是挖出了两个大优化空间。第一个空间是 context上下文复用。传统浏览器为每个新页面创建全新的 V8 Context所有内置对象、原型链都要重新初始化。Agent 的工作流有一个特点它反复访问的站点通常属于同一垂直领域这些页面加载的 JS 库React、Vue、jQuery 等高度重合。我在进程池内维护了一个热 context 缓存如果同一个域名下的多个标签页使用同一套基础库后打开的页面直接复用已初始化的 context只做轻量的隔离配置。这个优化的收益极大——团队里很多 React 应用的初始化耗时从 300ms 以上压到 40ms 左右。第二个空间是编译缓存。V8 会把编译后的字节码缓存到磁盘对应 Chrome 的 V8 Code Cache但 Chrome 的缓存策略偏向保守刷新页面时会重新编译一大半代码。我这边把缓存命中条件放宽了相同 URL、相同文件哈希、相同 context 指纹就使用缓存实测代码编译耗时减少 60%-70%。需要注意的是放宽缓存条件必须搭配稳定的文件哈希做校验否则缓存一旦脏了排查问题非常痛苦。我在这上面踩过坑后面避坑章节再细说。4.3 网络层优化Agent 场景下的请求合并与连接池策略网络往往是 Agent 任务等待时间的最大来源也是最被低估的优化点。Chrome 对同一域名的并发连接数限制为 6 个这套机制为了防止单个站点打爆服务器但对 Agent 场景来说过于保守——Agent 在同一时刻往往需要向同一个后端发起多次独立请求网络吞吐直接决定任务时长。我的做法是把并发上限从 6 抬到 24并按 Agent 工作负载做请求调度对实时性要求不高的次要请求图片、埋点、统计自动降级到低优先级队列在空闲时段才发送对 Agent 主动发起的 Fetch/XHR 请求永远以最高优先级执行并且不做 TCP 连接排队。这一项优化叠加的效果在带宽充足的环境里8 tab 并发采集任务的整体耗时又缩短了大约 30%。同时因为低优先级请求不会抢占 Agent 的业务请求任务的确定性反而更强了——之前时不时出现的页面加载完了但有个埋点请求卡了 2 秒这种间接等待在我这套调度下几乎不会发生。4.4 异步事件模型不再等待页面稳定这个伪命题传统的 Agent 式浏览器自动化最痛苦的环节是等待页面稳定。开发者一般会用sleep(2)、waitForSelector这样的策略无论用哪种方式都是在猜一个应该差不多好了的时间点。这个方案在广告多、异步多的真实页面上非常容易翻车——你认为的稳定信号比如 DOMContentLoaded早完成但真正要操作的那个 React 组件可能 5 秒后才渲染出来。这个项目里我建立了一套Mutation-Driven Event Loop页面 DOM 的任何变更会直接推送给我这套浏览器的事件队列不需要 Agent 主动轮询同时监听网络请求的开始与结束一旦触发会产生网络空闲信号。Agent 可以订阅DOM 稳定 网络空闲的组合条件当两个条件同时满足时交互才允许开始。这套机制把等待从时间猜测变成了确定性事件复杂交互流程的平均完成时间缩短了接近一半。背后其实是把传统浏览器内部的事件循环从渲染驱动改成Agent 需求驱动事件循环里没有 requestAnimationFrame、没有 Paint 任务只有 DOM 变更、网络事件和定时器每次循环的吞吐提升了几个数量级。5. 实际开发中的踩坑记录那些不会出现在论文里的现实教训这部分是全篇我最想写的。架构想清楚之后最花时间的不是搭骨架而是在真实页面环境中处理各种意想不到的反例。挑几个最典型的问题记录完整排查链路。5.1 事件驱动模型引发的死亡循环一面是效率一面是悬崖把事件循环改成 Mutation-Driven 之后第一次在真实的复杂 SPA 上测试就遇到了大麻烦页面永久假死。排查过程很典型当时我重启了服务、清了缓存最后才发现是事件循环里没有去重合并机制。复现路径是这样的一个 React 页面在初始化时连续触发了几十个 DOM 变更。每个变更都会触发我的 Mutation 监听回调而回调里如果 Agent 恰好注册了一个DOM 稳定后执行动作的规则这个动作会再次触发 DOM 变更变更又触发新的回调形成无限循环。Chrome 里不会出现这个问题因为它的渲染管线天然做了帧合并MutationObserver 回调是异步批处理模式而我的事件驱动模型是严格的即时模式缺少合并机制。解决方式不复杂在 Mutation 回调和事件队列之间加一层合并窗口将 10ms 内的所有变更合并为一条结构变更事件。等于把主线程的响应频率从每次变更降为每 10ms 一批吞吐保持不变但循环隐患消失了。此后我还在队列层加了一个变更深度计数一旦连续变更超过 200 次仍然没有稳定点就主动强制触发一次稳定快照防止极端情况下的事件风暴。5.2 JavaScript 编译缓存的脏数据问题调优反被调优误V8 缓存命中率优化后很快发现一个隐蔽 Bug缓存命中时脚本执行结果和原始执行不一致导致页面行为诡异。表现形式是某些页面偶发出现一模一样的请求参数返回结构不同。排查过程从网络层开始起先以为是连接池的状态污染后来逐步排查到 V8 context 复用时发现根源在编译缓存的指纹策略——我只校验了 URL 和文件大小没有校验文件内容哈希。服务器更新了 JS 文件内容但保留了相同 URL 和大小旧缓存被错误地命中自然就执行了旧版本的逻辑。修复很简单缓存键上加上完整文件哈希。但这个坑值得单独记录因为它说明了一个普遍问题——性能优化动作如果建立在宽松的条件判断上迟早会以数据一致性为代价还回来。后续我对所有缓存体系都统一了要求内容寻址优先。5.3 附带副作用的 iframeAgent 不需要的第三方内容仍在消耗资源砍掉渲染管线之后大部分第三方脚本广告 SDK、统计脚本依然会加载并执行。这些脚本大多是纯 JavaScript 逻辑它们不会画页面但还是会消耗 CPU 和内存。对 Agent 任务来说这些第三方逻辑既不产生业务价值还常常耽误主流程执行。我的处理是默认开启iframe 资源白名单模式只加载与主文档同域、或明确出现在 Agent 任务配置清单中的 iframe。第三方统计类的请求会被网络层直接拦截丢弃不进入解析管线。这对页面稳定性帮助很大——很多广告 SDK 的执行非常激进会不停重绘样式、申请内存在白名单模式下这些负担被整体切断。实测下来新闻类页面的平均内存进一步下降 30% 左右JS 执行次数下降 50% 以上。这里有一个需要注意的点白名单模式必须同时提供全部放行的兜底开关。有些 Agent 任务确实需要操作跨域 iframe比如第三方支付弹窗这时候默认策略反而会误伤。我的做法是白名单规则与每个 Agent 任务绑定而不是全局写死灵活性和可预测性兼顾。5.4 内存回收的激进策略从等到分配失败再回收到变化阈值即回收Chrome 的内存回收策略偏保守原因是要兼顾 UI 响应平滑不宜频繁触发 GC 造成用户可感知的卡顿。Agent 场景下没有这个顾虑GC 对 Agent 的干扰极小因为 Agent 不会因为页面卡了 300ms而产生挫败感只要任务继续推进就行。所以我把 GC 的触发策略改成了适应式的当页面每分钟的 DOM 变更数低于一个阈值比如 50 次且当前 JS 堆的已分配量超过一定比例比如 60%就主动触发一次全量 GC。这不只是一个参数调整而是把整个 GC 策略从无 UI 卡顿优先改成内存占用最小化优先。测下来长时间运行的 SPA 任务常驻内存进一步从几百 MB 降到 70-80 MB 区间任务完成时间和稳定性都没有受到负面影响。5.5 协议层的序列化开销一次过度设计的自我纠正项目早期我对协议层做了一套完整的 JSON Schema 定义用它来向 Agent 输出页面状态和绑定操作。设计时期望它能精确定义所有状态但实际跑起来发现序列化/反序列化开销非常大——高频状态同步时JSON.stringify 本身就要占单次操作耗时的 20% 以上。后来做了一个转折性的简化把全量状态输出改成增量变更流 按需全量快照。Agent 在启动时获取一次全量状态之后只接收 DOM 变更事件和相关节点的增量信息只有当 Agent 明确请求时才重新生成一次全量快照。这个改动把高频操作的单次耗时从 3.2ms 降到了 1.1ms代码实现也更简单了。我记录这个例子是因为它代表了一个设计倾向在面向 Agent 的协议设计里聪明的完整建模经常不如朴素的增量同步可靠——Agent 根本不关心协议美不美它只关心能不能快速拿到自己需要的状态。6. 不只适用于新浏览器这套方案思路在现有项目里的复用价值写到这里可能有人会觉得这个项目距离自己的实际工作太远——毕竟不是每个人都有资源去重写一个浏览器内核。但我的真实体验是这套方案里至少有四个思路可以平移到现有任何 Agent 工具链和浏览器自动化项目上不一定需要重造轮子。6.1 事件驱动替代轮询等待即使还在用 Playwright、Puppeteer 或者 Selenium也可以采用Mutation 网络空闲的信号驱动替代固定 sleep。具体做法是在所有操作之后不写死等待时间而是用MutationObserver监听目标容器变化同时监听网络请求的 start/end等两者都静默后再断言结果。这套做法比任何waitForTimeout都稳。不要小看这个改变真实业务里大量 Agent 失败案例都是 sleep 短了或长了导致的时序问题。6.2 资源按任务需要裁剪Agent 运行时默认关掉图片加载、关闭第三方 iframe、禁用不必要的插件与扩展只保留当前任务明确依赖的资源类型。包括在 Chrome 里也一样——很多人不知道--blink-settingsimagesEnabledfalse这个启动参数它可以让 Chrome 直接不加载图片对纯文本采集任务的内存收益非常明显。类似的参数还有禁用预加载、禁用后台标签节流--disable-background-timer-throttling、禁用渲染节流--disable-renderer-backgrounding。这些参数单独每个收益不大但叠加起来非常可观。6.3 V8 上下文复用与编译缓存思路如果你自己维护着一套 Electron 或 Node 写 Agent 工具可以考虑在应用层做进程池 context 复用避免反复初始化昂贵的 JS runtime。Node 的vm模块 模块加载缓存能实现类似效果。很多人没意识到的是Agent 每次打开新页面都会重新执行一遍 React 这类大库的初始化这个成本完全可以用复用干掉。6.4 协议层增量同步替代全量快照无论你的 Agent 是通过 CDP 还是其他协议和浏览器通信尽量设计增量事件流 按需快照而不是每步都全量拉取页面状态。全量快照在页面规模大时非常昂贵比如一个包含几百个节点的页面JSON 序列化一次可能就需要几十毫秒而高频操作之间往往只有几个节点的变化增量协议会把开销压到几毫秒。7. 适用边界与公平对比什么场景建议换什么场景留在 Chrome聊优点聊了很多也必须把边界讲清楚否则就是误导。这套专用浏览器不是万能的它对某些任务、某些目标用户确实毫无优势。7.1 适合切到专用浏览器的场景高并发采集与数据同步几十个页面并发抓取单个 Agent 每天处理数十万页面。这个量级下浏览器内存直接决定并发上限和成本。长时间运行的监测类 Agent每 30 秒刷新一次页面、比对数据变化。Chrome 在这种场景下要么会累积内存导致崩溃要么会被后台节流导致逻辑紊乱专用浏览器不会。大规模自动化测试如果是 CI 流水线里跑 E2E 测试并发运行多个浏览器实例很常见专用浏览器可以把单机的并发测试数提升一个数量级。复杂业务自动化多系统跨域流程操作需要反复在不同站点间切换、等待、校验状态DOM 变更驱动的事件模型能有效减少超时重试。7.2 不建议切换到专用浏览器的场景需要截图、录屏或视觉验证的任务这部分我砍掉了渲染管线天然做不到。需要验证页面布局是否正确、元素是否遮挡等问题Chrome 的渲染引擎依然是正确工具。依赖特定浏览器 API 或插件生态的场景比如某些金融网站强制使用特定安全控件这类场景需要完整浏览器兼容性自研轻内核很难完全覆盖。页面本身包含严重反自动化的 JS 代码而且这些代码对执行环境做了指纹检测那么轻内核可能更容易暴露异常特征不如直接用隐身模式加合理的操作节奏更稳妥。7.3 我如何看待7.6 倍这个指标抛开所有技术细节我最想强调的一点是一个性能指标的成立高度取决于对比基准和你对任务的定义。比 Chrome 快 7.6 倍这个数据严格来说应该在标题里加上一个前置条件在我测试的这三类 Agent 任务类型下。换一个场景比如人工打开网页刷新闻这个项目毫无优势。但如果在Agent 执行自动化任务这个语境下我认为这个对比是公平且可复现的——因为 Agent 场景的最终目标不是页面加载快而是任务完成快我的测试也全部基于任务完成时间而不是加载时间。实际体会一个反浏览器常识的工程实践项目从立项到现在大概花了四个月核心代码不到两万行但性能数据远超最初预期。我个人最大的收获反而不是这些指标而是对一个老问题的重新认识很多行业常识其实是场景假设的产物。浏览器就该渲染就该开多进程隔离就该为人类用户保持 UI 稳定——这些判断都成立但只适用于服务人类用户这一前提。一旦服务对象变成 AI Agent很多常识都需要重新审视。如果让我给同样在做 Agent 基础设施的同行一个建议我会说先别急着在应用层堆更多补偿逻辑回头看看基础设施层有没有更底层的浪费可以砍。我给 AI Agent 写专用浏览器这件事本质上就是砍掉了服务于人眼的那部分巨大开销。对应的思路完全可以用到 Agent 工具链的每个环节去掉为了通用而保留的冗余针对真实工作负载做减法性能的提升往往是指数级的而不是百分比级的。最后分享一个落地层面的提醒这类项目前期很容易陷入重新发明轮子的自我怀疑——毕竟 Chromium 那么好用、那么成熟。但只要你认真列出 Agent 任务的真实计算需求和通用浏览器提供的能力做一次系统对比你大概率会发现两者之间的错配比你想象的严重得多。这个错配就是这类项目的价值空间。至于最终是自研、裁剪还是混合取决于团队资源和节奏但看问题的视角建议尽早切换过来。