跳转至

[ISSUE-0066] dynamic-scraper.ts Map 加 onRemoved 兜底清理

v0.10.44 第三轮独立 audit agent 发现"可疑点 S2",归档 raw inbox。 2026-05-28 评估周期收口 — 4 行代码修,避免长期慢泄漏。

病灶

src/utils/dynamic-scraper.ts:13-37 注册: - webRequest.onCompleted + onErrorOccurred 监听 <all_urls> main_frame - 对每个用户浏览器导航写入 tabStatus / tabError Map - tab 关闭时无 browser.tabs.onRemoved 清理

影响(修复前评估)

维度 评估
每条 entry 大小 (number, number) < 100 字节
累积速度 每个新 tab + 1 条
1 个月累积量 普通用户 200 tab/天 → 6000 条 ≈ 600 KB
SW kill 频率 MV3 SW 闲置 kill 会自动重置 Map
实际危害 几乎可忽略(SW kill 已变相清理)

但严格意义上是泄漏,且代码意图明确:"Map 跟随 tab 生命周期"。

修(v0.10.86)

// ISSUE-0066: tab 关闭时清 Map,防长期慢泄漏
// MV3 SW 闲置 kill 已变相清理,但严格意义上仍是泄漏 — 加 onRemoved 兜底
if (browser.tabs?.onRemoved) {
  browser.tabs.onRemoved.addListener((tabId) => {
    tabStatus.delete(tabId);
    tabError.delete(tabId);
  });
}

browser.tabs?.onRemoved 用可选链兜底,理论上 chrome MV3 一定有,但和已有的 if (browser.webRequest) 保持同款守护风格。

未来防退化

无 audit_grep —— 单文件单 listener 的小修复,future 删 listener 会被 code review 看到。如果以后又被独立 agent 发现"加回去过又被删",再补 scan pattern。

元教训

raw inbox 的"低优先级技术债"也要有评估周期,否则会一直挂着: - 这条挂了 14 个 ISSUE(v0.10.44 → v0.10.86)才被处理 - 处理本身只花 10 分钟(含写 issue / build / commit) - 拖延成本 ≪ 修复成本

新工作流(v0.10.86 起):发版前扫一眼 _todo.md,能秒杀的(< 30min)就顺手做,做不掉的才留 inbox。

相关

  • [[2026-05-26-dynamic-scraper-tabstatus-map-leak|2026-05-26-dynamic-scraper-tabStatus-Map泄漏]] — 原始发现(v0.10.44 agent S2)
  • [[0028-captcha-resume-missing-map-schedule|0028-拦截恢复漏调地图调度]] — 同 dynamic-scraper.ts 历史 issue