打开网易新闻 查看精彩图片

Chrome没有崩溃。它只是让我的电脑慢慢窒息。

内存占用 creeping up,后台标签页堆积如山,其他应用开始冻结,风扇狂转。但表面看一切正常——没有单个标签页是罪魁祸首。

一位开发者花了6个月,用Rust写了一套浏览器扩展+原生宿主的双层架构,让Chrome终于学会了"看脸色行事"。

问题根源:浏览器成了操作系统,却不懂系统状态

现代浏览器本身就是操作系统。Chrome每个标签页独立进程,沙盒隔离,这本是好设计。

但当系统内存吃紧时,浏览器依然我行我素。它不知道风扇为什么转,不知道电池还剩多少,更不知道用户此刻真正需要哪些标签页。

市面上现有的标签页休眠工具,逻辑简单粗暴:X分钟不用就冻结。开发者形容这是"盲人摸象"——

不管系统是否在内存压力下挣扎,不管CPU是否正在飙升,不管你是否插着电源,也不管这个标签页是否属于当前工作流的一部分。

它们按时间决策,而非按状态决策。

这位开发者想要的是:确定性、压力感知、上下文敏感的生命周期引擎。不要AI黑箱,不要云端分析,就一个结构清晰的系统。

架构设计:为什么必须把Rust拽进来

架构设计:为什么必须把Rust拽进来

写代码前,他先给自己定了铁律:行为必须可解释,不上传任何数据到云端,绝不碰用户正在用的或固定的标签页,所有决策要基于系统压力和上下文启发。

最关键的约束是"职责分离"。这直接决定了最终架构——

Chrome扩展(MV3)负责标签页活动追踪、焦点聚类、TTL门控;Rust原生宿主负责采集系统指标(内存、CPU、电池)、计算压力分数、做确定性分类。两者通过Chrome的原生消息API通信。

「Chrome扩展无法可靠获取底层系统指标,比如真实的内存压力。」开发者在文档里解释,「所以我把职责切开:浏览器逻辑留在浏览器里,系统逻辑用原生代码实现。」

这种分离让系统保持干净。扩展不用hack权限去偷窥系统,Rust程序也不用操心DOM和标签页状态。

压力评分:不是看内存百分比,而是算"加权窒息指数"

压力评分:不是看内存百分比,而是算"加权窒息指数"

最直接的思路是:内存用到80%就动手?太糙了。

开发者建了一套加权压力评分模型。Rust宿主采集三类数据——

原始内存指标:可用内存、已用比例、交换空间活跃度;CPU状态:整体负载、浏览器进程占比;电源状态:是否电池供电、剩余电量档位。

然后算出一个0-100的压力分数。内存是主导信号,CPU作为修正因子,电池状态只影响激进程度。

「目标不是完美,是一致且可解释。」他写道。系统会给每个决策打上理由标签,比如「HIGH pressure because RAM_HIGH + ON_BATTERY」。这种透明性让用户知道为什么某个标签页被冻结了。

焦点聚类:你的"工作流"比时间更重要

焦点聚类:你的"工作流"比时间更重要

传统工具一视同仁:30分钟不碰就杀。但开发者意识到,一个30分钟前打开、属于当前工作流的标签页,和另一个窗口里被遗忘的标签页,完全是两码事。

于是他引入了Focus Mode。

焦点聚类的依据包括:当前激活的标签页、最近交互的窗口、标签页之间的打开关系链(比如从A页面点击链接打开的B页面)。

处于"焦点聚类"内的标签页,TTL更长;聚类外的标签页,在压力下更快过期。这让系统既尊重用户的实际工作流,又保持确定性——没有神经网络,没有概率猜测,就是更聪明的规则引擎。

实际运行:一个标签页的生死流程

实际运行:一个标签页的生死流程

系统启动后,扩展开始追踪每个标签页的最后激活时间、所属窗口、页面可见性状态。Rust宿主每秒采样系统指标,计算压力分数。

当压力分数越过阈值,宿主向扩展发送信号。扩展检查候选标签页:是否在焦点聚类内?是否被用户固定?是否正在播放音频?是否包含未提交的表单输入?

通过所有检查的标签页进入"待休眠队列",按优先级排序。扩展执行冻结操作前,会尝试保存页面状态——滚动位置、表单内容、甚至某些单页应用的内存状态。

用户切回被冻结的标签页时,扩展优先尝试恢复状态。如果恢复失败,才重新加载页面。

为什么选Rust:不是跟风,是算账

为什么选Rust:不是跟风,是算账

原生宿主的语言选择,开发者有过权衡。Go的GC暂停可能卡在关键采样时刻;C++让他害怕内存安全问题,毕竟这个程序要长期驻留系统;Python和Node的资源占用本身就成了问题。

Rust的零成本抽象、无GC、跨平台编译支持,让它成为"系统级守护进程"的合理选择。编译后的单二进制文件,Windows上跑起来内存占用不到15MB。

「我不想在解决Chrome内存问题的同时,引入另一个内存大户。」

代码结构也体现了Rust的模块化哲学。指标采集层抽象出平台接口,Linux用sysinfo+procfs,macOS用sysctl和IOKit,Windows计划用WMI或性能计数器。压力评分引擎纯函数式,输入系统状态,输出分数和理由标签,无副作用,方便测试。

局限与妥协:MV3是一堵墙

局限与妥协:MV3是一堵墙

Chrome的Manifest V3给这个项目带来了真实阻力。服务工作者(Service Worker)的休眠机制,让扩展无法持续保持状态。原生消息通道的启动延迟,意味着系统压力飙升时,扩展可能还没收到Rust宿主的信号。

开发者的 workaround 是:扩展维护一个本地优先的"压力缓存",结合自身的轻量级启发式,在通道不可用时也能做出保守决策。Rust宿主启动时,会批量同步最近的历史压力数据,帮助扩展校准。

另一个妥协是跨平台。macOS的内存压力指标比Linux更"抽象",苹果不直接暴露可用内存,而是给一个"内存压力等级"。开发者花了额外时间对齐不同平台的语义,确保评分模型的一致性。

用户反馈:从"这有用吗"到"关掉后才发现离不开"

用户反馈:从"这有用吗"到"关掉后才发现离不开"

项目开源后,最让开发者意外的反馈来自一位拥有127个固定标签页的用户。对方说:「我以为这种工具对我没用,毕竟我固定了这么多。但它居然识别出其中30多个其实属于'已完成项目'的聚类,在内存紧张时帮我冻结了。我没丢任何状态,但风扇安静了。」

另一位用户贡献了电池场景的数据: unplugged 状态下,系统更激进地冻结后台标签页,笔记本续航从4小时延长到5.5小时。「不是魔法,就是它真的在'电池模式'下动了手。」

也有批评。有用户抱怨焦点聚类的误判——某个标签页明明还在用,因为切去查了5分钟资料,就被划到聚类外冻结了。开发者回应说,这是TTL参数和聚类边界敏感度的权衡,后续版本会开放更细粒度的调节。

开源与后续:一个实验的边界

开源与后续:一个实验的边界

项目代码托管在GitHub,采用MIT许可证。开发者明确表示,这是"实验性架构验证",不承诺长期维护,也不建议非技术用户直接部署——安装需要编译Rust代码、配置Chrome的本地消息宿主清单,门槛不低。

但他留下了详细的架构文档和构建指南,希望有人能把这个思路做成更成熟的产品。或者,更希望Chrome团队自己把这个逻辑做进浏览器。

「浏览器厂商有系统级权限,他们可以做得更优雅。我只是证明:即使没有那些权限,用现有的扩展API和原生消息机制,也能造出足够好用的东西。」

如果Chrome哪天内置了"系统压力感知"的标签页管理,这个Rust项目的价值或许就只剩下"我们早就试过了"。但对那位开发者来说,这6个月的折腾已经值了——他的笔记本风扇终于不再像要起飞一样。

你会愿意让浏览器根据你的电池剩余量和当前工作流,自动决定哪些标签页该"睡一会儿"吗?还是说,你更信任自己手动点那个×?